home *** CD-ROM | disk | FTP | other *** search
/ Aminet 51 / Aminet 51 (2002)(GTI - Schatztruhe)[!][Oct 2002].iso / Aminet / util / arc / xadmasterdev.lha / xad / Sources / clients / StuffIt.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-20  |  102.1 KB  |  3,290 lines

  1. #ifndef XADMASTER_STUFFIT_C
  2. #define XADMASTER_STUFFIT_C
  3.  
  4. /* Programmheader
  5.  
  6.         Name:           StuffIt.c
  7.         Main:           xadmaster
  8.         Versionstring:  $VER: StuffIt.c 1.11 (21.07.2002)
  9.         Author:         SDI
  10.         Distribution:   GPL
  11.         Description:    StuffIt file archiver client
  12.  
  13.  1.0   23.08.00 : first version
  14.  1.1   23.10.00 : first complete StuffIt5 scanner, StuffIt5-Exe
  15.  1.2   30.10.00 : now uses xadIO.c for all algorithms
  16.  1.3   14.07.01 : added algorithm 8, uses xadAddEntry funcs
  17.  1.4   12.08.01 : added MacBinary client, added StuffIt fixes
  18.  1.5   19.09.01 : finally added algorithm 13
  19.  1.6   02.10.01 : little fixes, added ID's
  20.  1.7   30.12.01 : added algorithm 14
  21.  1.8   19.01.02 : added PackIt archiver
  22.  1.9   24.03.02 : added character conversion
  23.  1.10  24.06.02 : added new version 12 charset stuff
  24.  1.11  21.07.02 : added algorithm 15
  25. */
  26.  
  27. /* StuffIt file archiver client for XAD.
  28.  * Copyright (C) 2000-2002 Dirk Stöcker <stoecker@epost.de>
  29.  *
  30.  * little based on macutils 2.0b3 macunpack by Dik T. Winter
  31.  * Copyright (C) 1992 Dik T. Winter <dik@cwi.nl>
  32.  *
  33.  * algorithm 15 is based on the work of  Matthew T. Russotto
  34.  * Copyright (C) 2002 Matthew T. Russotto <russotto@speakeasy.net>
  35.  * http://www.speakeasy.org/~russotto/arseniccomp.html
  36.  *
  37.  * This program is free software; you can redistribute it and/or modify
  38.  * it under the terms of the GNU General Public License as published by
  39.  * the Free Software Foundation; either version 2 of the License, or
  40.  * (at your option) any later version.
  41.  * 
  42.  * This program is distributed in the hope that it will be useful,
  43.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  44.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  45.  * GNU General Public License for more details.
  46.  * 
  47.  * You should have received a copy of the GNU General Public License
  48.  * along with this program; if not, write to the Free Software
  49.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  50.  */
  51.  
  52. //#define DEBUG
  53.  
  54. #include <proto/xadmaster.h>
  55. #include <exec/memory.h>
  56. #include "SDI_compiler.h"
  57. #include "ConvertE.c"
  58. #define XADIOGETBITSHIGH
  59. #define XADIOGETBITSLOW
  60. #define XADIOREADBITSLOW
  61. #include "xadIO.c"
  62. #include "xadCPU.h"
  63. #define SDI_TO_ANSI
  64. #include "SDI_ASM_STD_protos.h"
  65.  
  66. #ifndef XADMASTERFILE
  67. #define SIT_Client              FirstClient
  68. #define NEXTCLIENT              0
  69. #define XADMASTERVERSION        12
  70. UBYTE version[] = "$VER: StuffIt 1.11 (21.07.2002)" CPUTEXT " GPL by Dirk Stöcker";
  71. #endif
  72. #define SIT_VERSION             1
  73. #define SIT_REVISION            11
  74. #define SIT5_VERSION            SIT_VERSION
  75. #define SIT5_REVISION           SIT_REVISION
  76. #define SIT5EXE_VERSION         SIT_VERSION
  77. #define SIT5EXE_REVISION        SIT_REVISION
  78. #define MACBINARY_VERSION       SIT_VERSION
  79. #define MACBINARY_REVISION      SIT_REVISION
  80. #define PACKIT_VERSION          SIT_VERSION
  81. #define PACKIT_REVISION         SIT_REVISION
  82.  
  83. #define SITFH_COMPRMETHOD    0 /* UBYTE rsrc fork compression method */
  84. #define SITFH_COMPDMETHOD    1 /* UBYTE data fork compression method */
  85. #define SITFH_FNAMESIZE      2 /* UBYTE filename size */
  86. #define SITFH_FNAME          3 /* UBYTE 83 byte filename */
  87. #define SITFH_FTYPE         66 /* ULONG file type */
  88. #define SITFH_CREATOR       70 /* ULONG file creator */
  89. #define SITFH_FNDRFLAGS     74 /* UWORD Finder flags */
  90. #define SITFH_CREATIONDATE  76 /* ULONG creation date */
  91. #define SITFH_MODDATE       80 /* ULONG modification date */
  92. #define SITFH_RSRCLENGTH    84 /* ULONG decompressed rsrc length */
  93. #define SITFH_DATALENGTH    88 /* ULONG decompressed data length */
  94. #define SITFH_COMPRLENGTH   92 /* ULONG compressed rsrc length */
  95. #define SITFH_COMPDLENGTH   96 /* ULONG compressed data length */
  96. #define SITFH_RSRCCRC      100 /* UWORD crc of rsrc fork */
  97. #define SITFH_DATACRC      102 /* UWORD crc of data fork */ /* 6 reserved bytes */
  98. #define SITFH_HDRCRC       110 /* UWORD crc of file header */
  99. #define SIT_FILEHDRSIZE    112
  100.  
  101. #define SITAH_SIGNATURE    0 /* ULONG signature = 'SIT!' */
  102. #define SITAH_NUMFILES     4 /* UWORD number of files in archive */
  103. #define SITAH_ARCLENGTH    6 /* ULONG arcLength length of entire archive incl. header */
  104. #define SITAH_SIGNATURE2  10 /* ULONG signature2 = 'rLau' */
  105. #define SITAH_VERSION     14 /* UBYTE version number */
  106. #define SIT_ARCHDRSIZE    22 /* +7 reserved bytes */
  107.  
  108. /* compression methods */
  109. #define SITnocomp       0       /* just read each byte and write it to archive */
  110. #define SITrle          1       /* RLE compression */
  111. #define SITlzc          2       /* LZC compression */
  112. #define SIThuffman      3       /* Huffman compression */
  113.  
  114. #define SITlzah         5       /* LZ with adaptive Huffman */
  115. #define SITfixhuf       6       /* Fixed Huffman table */
  116.  
  117. #define SITmw           8       /* Miller-Wegman encoding */
  118.  
  119. #define SITprot         16      /* password protected bit */
  120. #define SITsfolder      32      /* start of folder */
  121. #define SITefolder      33      /* end of folder */
  122.  
  123. struct SITPrivate {
  124.   UWORD CRC;
  125.   UBYTE Method;
  126. };
  127.  
  128. #define SITPI(a)        ((struct SITPrivate *) ((a)->xfi_PrivateInfo))
  129.  
  130. /*****************************************************************************/
  131.  
  132. static UWORD crctable[256] = {
  133.   0x0000,0x1021,0x2042,0x3063,0x4084,0x50A5,0x60C6,0x70E7,0x8108,0x9129,
  134.   0xA14A,0xB16B,0xC18C,0xD1AD,0xE1CE,0xF1EF,0x1231,0x0210,0x3273,0x2252,
  135.   0x52B5,0x4294,0x72F7,0x62D6,0x9339,0x8318,0xB37B,0xA35A,0xD3BD,0xC39C,
  136.   0xF3FF,0xE3DE,0x2462,0x3443,0x0420,0x1401,0x64E6,0x74C7,0x44A4,0x5485,
  137.   0xA56A,0xB54B,0x8528,0x9509,0xE5EE,0xF5CF,0xC5AC,0xD58D,0x3653,0x2672,
  138.   0x1611,0x0630,0x76D7,0x66F6,0x5695,0x46B4,0xB75B,0xA77A,0x9719,0x8738,
  139.   0xF7DF,0xE7FE,0xD79D,0xC7BC,0x48C4,0x58E5,0x6886,0x78A7,0x0840,0x1861,
  140.   0x2802,0x3823,0xC9CC,0xD9ED,0xE98E,0xF9AF,0x8948,0x9969,0xA90A,0xB92B,
  141.   0x5AF5,0x4AD4,0x7AB7,0x6A96,0x1A71,0x0A50,0x3A33,0x2A12,0xDBFD,0xCBDC,
  142.   0xFBBF,0xEB9E,0x9B79,0x8B58,0xBB3B,0xAB1A,0x6CA6,0x7C87,0x4CE4,0x5CC5,
  143.   0x2C22,0x3C03,0x0C60,0x1C41,0xEDAE,0xFD8F,0xCDEC,0xDDCD,0xAD2A,0xBD0B,
  144.   0x8D68,0x9D49,0x7E97,0x6EB6,0x5ED5,0x4EF4,0x3E13,0x2E32,0x1E51,0x0E70,
  145.   0xFF9F,0xEFBE,0xDFDD,0xCFFC,0xBF1B,0xAF3A,0x9F59,0x8F78,0x9188,0x81A9,
  146.   0xB1CA,0xA1EB,0xD10C,0xC12D,0xF14E,0xE16F,0x1080,0x00A1,0x30C2,0x20E3,
  147.   0x5004,0x4025,0x7046,0x6067,0x83B9,0x9398,0xA3FB,0xB3DA,0xC33D,0xD31C,
  148.   0xE37F,0xF35E,0x02B1,0x1290,0x22F3,0x32D2,0x4235,0x5214,0x6277,0x7256,
  149.   0xB5EA,0xA5CB,0x95A8,0x8589,0xF56E,0xE54F,0xD52C,0xC50D,0x34E2,0x24C3,
  150.   0x14A0,0x0481,0x7466,0x6447,0x5424,0x4405,0xA7DB,0xB7FA,0x8799,0x97B8,
  151.   0xE75F,0xF77E,0xC71D,0xD73C,0x26D3,0x36F2,0x0691,0x16B0,0x6657,0x7676,
  152.   0x4615,0x5634,0xD94C,0xC96D,0xF90E,0xE92F,0x99C8,0x89E9,0xB98A,0xA9AB,
  153.   0x5844,0x4865,0x7806,0x6827,0x18C0,0x08E1,0x3882,0x28A3,0xCB7D,0xDB5C,
  154.   0xEB3F,0xFB1E,0x8BF9,0x9BD8,0xABBB,0xBB9A,0x4A75,0x5A54,0x6A37,0x7A16,
  155.   0x0AF1,0x1AD0,0x2AB3,0x3A92,0xFD2E,0xED0F,0xDD6C,0xCD4D,0xBDAA,0xAD8B,
  156.   0x9DE8,0x8DC9,0x7C26,0x6C07,0x5C64,0x4C45,0x3CA2,0x2C83,0x1CE0,0x0CC1,
  157.   0xEF1F,0xFF3E,0xCF5D,0xDF7C,0xAF9B,0xBFBA,0x8FD9,0x9FF8,0x6E17,0x7E36,
  158.   0x4E55,0x5E74,0x2E93,0x3EB2,0x0ED1,0x1EF0
  159. };
  160.  
  161. static UWORD DoCRC(UBYTE * Mem, LONG Size)
  162. {
  163.   UWORD CRC = 0;
  164.  
  165.   while(Size--)
  166.     CRC = crctable[((CRC>>8) ^ *(Mem++)) & 0xFF] ^ (CRC<<8);
  167.  
  168.   return CRC;
  169. }
  170.  
  171. /*****************************************************************************/
  172.  
  173. #define STUFFITMAXALGO  15
  174. static const STRPTR sittypes[] = {
  175. "NoComp", "RLE", "LZC", "Huffmann", "4", "LZAH", "FixHuff", "7", "MW",
  176. "9", "10", "11", "12", "TableHuff", "Installer", "Arsenic"};
  177.  
  178. ASM(BOOL) SIT_RecogData(REG(d0, ULONG size), REG(a0, UBYTE *data),
  179. REG(a6, struct xadMasterBase *xadMasterBase))
  180. { CPUCHECK
  181.   if(EndGetM32(data+10) == 0x724C6175)
  182.   {
  183.     if(EndGetM32(data) == 0x53495421)
  184.       return 1;
  185.     /* Installer archives? */
  186.     if(data[0] == 'S' && data[1] == 'T')
  187.     {
  188.       if(data[2] == 'i')
  189.       {
  190.         if(data[3] == 'n' || (data[3] >= '0' && data[3] <= '9'))
  191.           return 1;
  192.       }
  193.       else if(data[2] >= '0' && data[2] <= '9' && data[3] >= '0' && data[3] <= '9')
  194.         return 1;
  195.     }
  196.   }
  197.   return 0;
  198. }
  199.  
  200. /*****************************************************************************/
  201.  
  202. #ifdef DEBUG
  203. #include <proto/intuition.h>
  204. #include <proto/exec.h>
  205. static void UnknownRequest(struct xadMasterBase *xadMasterBase, ULONG num, STRPTR name)
  206. {
  207.   struct IntuitionBase *IntuitionBase;
  208.   struct ExecBase *SysBase = xadMasterBase->xmb_SysBase;
  209.   
  210.   if((IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37)))
  211.   {
  212.     struct EasyStruct easystruct;
  213.  
  214.     memset(&easystruct, 0, sizeof(struct EasyStruct));
  215.  
  216.     easystruct.es_StructSize = sizeof(struct EasyStruct);
  217.     easystruct.es_Title = "Required test-file detected";
  218.     easystruct.es_GadgetFormat = "ok";
  219.     if(num)
  220.     {
  221.       easystruct.es_TextFormat = "The Client 'Stuffit' detected unknown algorithm %ld.\n"
  222.       "Please send me this archive file.\n"
  223.       "The filename maybe '%s'";
  224.       EasyRequest(0, &easystruct, 0, num, name ? name : "");
  225.     }
  226.     else
  227.     {
  228.       easystruct.es_TextFormat = "The Client 'Stuffit' detected an unknown archive structure.\n"
  229.       "Please send me this archive file.\n"
  230.       "The filename maybe '%s'";
  231.       EasyRequest(0, &easystruct, 0, name ? name : "");
  232.     }
  233.     CloseLibrary((struct Library *) IntuitionBase);
  234.   }
  235. }
  236. #endif
  237.  
  238. static STRPTR MACname(struct xadMasterBase *xadMasterBase, struct xadFileInfo *dir, STRPTR file, ULONG size, ULONG rsrc)
  239. {
  240.   return xadConvertName(CHARSET_HOST,
  241.   XAD_XADSTRING, dir ? dir->xfi_FileName : 0,
  242.   XAD_CHARACTERSET, CHARSET_MACOS,
  243.   XAD_STRINGSIZE, size,
  244.   XAD_CSTRING, file,
  245.   XAD_CHARACTERSET, CHARSET_ISO_8859_1,          /* the .rsrc ending */
  246.   XAD_ADDPATHSEPERATOR, FALSE,
  247.   rsrc ? XAD_CSTRING : TAG_IGNORE, ".rsrc",
  248.   TAG_DONE);
  249. }
  250.  
  251. static LONG SITmakecomment(STRPTR txt, UWORD creatorflags, STRPTR comment, ULONG csize, STRPTR dest)
  252. {
  253.   LONG i, res = 0;
  254.  
  255.   if(csize)
  256.     res = 15+csize+1;
  257.   else
  258.   {
  259.     for(i = 0; i < 8 && txt[i] >= 0x20 && txt[i] <= 0x7E; ++i)
  260.       ;
  261.     if(i == 8)
  262.       res = 15;
  263.   }
  264.   if(res && dest)
  265.   {
  266.     for(i = 0; i < 4; ++i)
  267.       *(dest++) = txt[i] >= 0x20 && txt[i] <= 0x7E ? txt[i] : '_';
  268.     *(dest++) = '/';
  269.     for(; i < 8; ++i)
  270.       *(dest++) = txt[i] >= 0x20 && txt[i] <= 0x7E ? txt[i] : '_';
  271.     *(dest++) = ' ';
  272.     for(i = 0; i < 4 ; ++i)
  273.     {
  274.       creatorflags &= 0xFFFF; /* security */
  275.       *(dest++) = (creatorflags >= 0xA000 ? 'A'-10 : '0') + (creatorflags >> 12);
  276.       creatorflags <<= 4;
  277.     }
  278.     if(csize)
  279.     {
  280.       *(dest++) = ' ';
  281.       while(csize--)
  282.       {
  283.         *(dest++) = *comment >= 0x20 && *comment <= 0x7E ? *comment : '_';
  284.         ++comment;
  285.       }
  286.     }
  287.     *dest = 0;
  288.   }
  289.   return res;
  290. }
  291.  
  292. ASM(LONG) SIT_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  293. REG(a6, struct xadMasterBase *xadMasterBase))
  294. {
  295.   UBYTE sithdr[SIT_FILEHDRSIZE];
  296.   struct xadFileInfo *fi, *ldir = 0, *lfi = 0;
  297.   LONG err;
  298.   ULONG nsize, csize, fullsize;
  299.  
  300.  
  301.   fullsize = ai->xai_InSize;
  302.   if(!(err = xadHookAccess(XADAC_READ, 22, sithdr, ai)))
  303.   {
  304.     if(sithdr[2] == 'i')
  305.     {
  306.       csize = EndGetM32(sithdr+SITAH_ARCLENGTH);
  307.       if(csize < fullsize)
  308.         fullsize = csize;
  309.     }
  310. #ifdef DEBUG
  311. #define MAKESIT(a,b,c,d) ((ULONG) ((a)<<24) | (ULONG) ((b)<<16) | (ULONG) ((c)<<8) | (ULONG) (d))
  312.  
  313. switch(EndGetM32(sithdr))
  314. {
  315. case MAKESIT('S','I','T','!'):
  316. case MAKESIT('S','T','4','6'):
  317. case MAKESIT('S','T','5','0'):
  318. case MAKESIT('S','T','6','0'):
  319. case MAKESIT('S','T','6','5'):
  320. case MAKESIT('S','T','i','n'):
  321. case MAKESIT('S','T','i','2'):
  322. case MAKESIT('S','T','i','3'):
  323. case MAKESIT('S','T','i','4'):
  324.   break;
  325. default: UnknownRequest(xadMasterBase, 0, ai->xai_InName);
  326. }
  327. #endif
  328.     while(!err && ai->xai_InPos+SIT_FILEHDRSIZE <= fullsize)
  329.     {
  330.       if(!(err = xadHookAccess(XADAC_READ, SIT_FILEHDRSIZE, sithdr, ai)))
  331.       {
  332.         if(EndGetM16(sithdr+SITFH_HDRCRC) == xadCalcCRC16(XADCRC16_ID1, 0, 110, sithdr))
  333.         {
  334.           for(nsize = 0; nsize < 8; ++nsize)
  335.           {
  336.             if(sithdr[SITFH_FTYPE+nsize] < 0x20 || sithdr[SITFH_FTYPE+nsize] > 0x7E)
  337.               sithdr[SITFH_FTYPE+nsize] = '?';
  338.           }
  339.  
  340.           if(sithdr[SITFH_FNAMESIZE] > 83)
  341.             nsize = 83; /* prevent errors */
  342.           else
  343.             nsize = sithdr[SITFH_FNAMESIZE];
  344.           if(sithdr[SITFH_COMPRMETHOD] == SITefolder || sithdr[SITFH_COMPDMETHOD] == SITefolder)
  345.           {
  346.             ldir = (struct xadFileInfo *) ldir->xfi_PrivateInfo;
  347.           }
  348.           else if(sithdr[SITFH_COMPRMETHOD] == SITsfolder || sithdr[SITFH_COMPDMETHOD] == SITsfolder)
  349.           {
  350.             if((fi = xadAllocObjectA(XADOBJ_FILEINFO, 0)))
  351.             {
  352.               if((fi->xfi_FileName = MACname(xadMasterBase, ldir, sithdr+SITFH_FNAME, nsize, 0)))
  353.               {
  354.                 fi->xfi_Flags |= XADFIF_DIRECTORY|XADFIF_XADSTRFILENAME;
  355.                 xadConvertDates(XAD_DATEMAC, EndGetM32(&sithdr[SITFH_MODDATE]), XAD_GETDATEXADDATE,
  356.                 &fi->xfi_Date, TAG_DONE);
  357.                 fi->xfi_PrivateInfo = (APTR) ldir;
  358.                 ldir = fi;
  359.                 err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos, TAG_DONE);
  360.               }
  361.               else
  362.               {
  363.                 xadFreeObjectA(fi, 0);
  364.                 err = XADERR_NOMEMORY;
  365.               }
  366.             }
  367.             else
  368.               err = XADERR_NOMEMORY;
  369.           }
  370.           else
  371.           {
  372.             csize = SITmakecomment(sithdr + SITFH_FTYPE, EndGetM16(&sithdr[SITFH_FNDRFLAGS]), 0, 0, 0);
  373.  
  374.             if(EndGetM32(&sithdr[SITFH_RSRCLENGTH]))
  375.             {
  376.               if((fi = xadAllocObject(XADOBJ_FILEINFO, XAD_OBJPRIVINFOSIZE, sizeof(struct SITPrivate),
  377.               EndGetM32(&sithdr[SITFH_DATALENGTH]) || !csize ?
  378.               TAG_IGNORE : XAD_OBJCOMMENTSIZE, csize, TAG_DONE)))
  379.               {
  380.                 if((fi->xfi_FileName = MACname(xadMasterBase, ldir, sithdr+SITFH_FNAME, nsize, 1)))
  381.                 {
  382.                   /* if comment field is zero, nothing is done! */
  383.                   SITmakecomment(sithdr + SITFH_FTYPE, EndGetM16(&sithdr[SITFH_FNDRFLAGS]), 0, 0, fi->xfi_Comment);
  384.  
  385.                   fi->xfi_CrunchSize = EndGetM32(&sithdr[SITFH_COMPRLENGTH]);
  386.                   fi->xfi_Size = EndGetM32(&sithdr[SITFH_RSRCLENGTH]);
  387.  
  388.                   fi->xfi_Flags |= XADFIF_SEEKDATAPOS|XADFIF_MACRESOURCE|XADFIF_EXTRACTONBUILD|XADFIF_XADSTRFILENAME;
  389.                   fi->xfi_DataPos = ai->xai_InPos;
  390.                   lfi = fi;
  391.  
  392.                   SITPI(fi)->CRC = EndGetM16(&sithdr[SITFH_RSRCCRC]);
  393.                   SITPI(fi)->Method = sithdr[SITFH_COMPRMETHOD]&15;
  394.  
  395.                   if(!fi->xfi_Size && !SITPI(fi)->Method)
  396.                     fi->xfi_Size = fi->xfi_CrunchSize;
  397.  
  398. #ifdef DEBUG
  399.   if(SITPI(fi)->Method != 0 && SITPI(fi)->Method != 2 && SITPI(fi)->Method != 3 &&
  400.   SITPI(fi)->Method != 5 && SITPI(fi)->Method != 8 && SITPI(fi)->Method != 13 && SITPI(fi)->Method != 14
  401.   && SITPI(fi)->Method != 15)
  402.   {
  403.     xadHookAccess(0,SITPI(fi)->Method,0,ai);
  404.     UnknownRequest(xadMasterBase, SITPI(fi)->Method, ai->xai_InName);
  405.   }
  406. #endif
  407.                   xadConvertDates(XAD_DATEMAC, EndGetM32(&sithdr[SITFH_MODDATE]), XAD_GETDATEXADDATE, &fi->xfi_Date, TAG_DONE);
  408.  
  409.                   if(SITPI(fi)->Method <= STUFFITMAXALGO)
  410.                     fi->xfi_EntryInfo = sittypes[SITPI(fi)->Method];
  411.                   if(sithdr[SITFH_COMPRMETHOD]&SITprot)
  412.                   {
  413.                     fi->xfi_Flags |= XADFIF_CRYPTED;
  414.                     ai->xai_Flags |= XADAIF_CRYPTED;
  415.                   }
  416.  
  417.                   err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos+fi->xfi_CrunchSize, TAG_DONE);
  418.                 }
  419.                 else
  420.                 {
  421.                   xadFreeObjectA(fi, 0);
  422.                   err = XADERR_NOMEMORY;
  423.                 }
  424.               }
  425.               else
  426.                 err = XADERR_NOMEMORY;
  427.             }
  428.  
  429.             if(!err && (EndGetM32(&sithdr[SITFH_DATALENGTH]) || !EndGetM32(&sithdr[SITFH_RSRCLENGTH])))
  430.             {
  431.               if((fi = xadAllocObject(XADOBJ_FILEINFO, XAD_OBJPRIVINFOSIZE, sizeof(struct SITPrivate),
  432.               csize ? XAD_OBJCOMMENTSIZE : TAG_IGNORE, csize, TAG_DONE)))
  433.               {
  434.                 if((fi->xfi_FileName = MACname(xadMasterBase, ldir, sithdr+SITFH_FNAME, nsize, 0)))
  435.                 {
  436.                   SITmakecomment(sithdr + SITFH_FTYPE, EndGetM16(&sithdr[SITFH_FNDRFLAGS]), 0, 0, fi->xfi_Comment);
  437.  
  438.                   fi->xfi_CrunchSize = EndGetM32(&sithdr[SITFH_COMPDLENGTH]);
  439.                   fi->xfi_Size = EndGetM32(&sithdr[SITFH_DATALENGTH]);
  440.  
  441.                   fi->xfi_Flags |= XADFIF_SEEKDATAPOS|XADFIF_MACDATA|XADFIF_EXTRACTONBUILD|XADFIF_XADSTRFILENAME;
  442.                   fi->xfi_DataPos = ai->xai_InPos;
  443.  
  444.                   if(EndGetM32(&sithdr[SITFH_RSRCLENGTH]))
  445.                   {
  446.                     fi->xfi_MacFork = lfi;
  447.                     lfi->xfi_MacFork = fi;
  448.                   }
  449.  
  450.                   SITPI(fi)->CRC = EndGetM16(&sithdr[SITFH_DATACRC]);
  451.                   SITPI(fi)->Method = sithdr[SITFH_COMPDMETHOD]&15;
  452.  
  453.                   if(!fi->xfi_Size && !SITPI(fi)->Method)
  454.                     fi->xfi_Size = fi->xfi_CrunchSize;
  455.  
  456. #ifdef DEBUG
  457.   if(SITPI(fi)->Method != 0 && SITPI(fi)->Method != 2 && SITPI(fi)->Method != 3 &&
  458.   SITPI(fi)->Method != 5 && SITPI(fi)->Method != 8 && SITPI(fi)->Method != 13 && SITPI(fi)->Method != 14
  459.   && SITPI(fi)->Method != 15)
  460.   {
  461.     xadHookAccess(0,SITPI(fi)->Method,0,ai);
  462.     UnknownRequest(xadMasterBase, SITPI(fi)->Method, ai->xai_InName);
  463.   }
  464. #endif
  465.                   xadConvertDates(XAD_DATEMAC, EndGetM32(&sithdr[SITFH_MODDATE]),
  466.                   XAD_GETDATEXADDATE, &fi->xfi_Date, TAG_DONE);
  467.  
  468.                   if(SITPI(fi)->Method <= STUFFITMAXALGO)
  469.                     fi->xfi_EntryInfo = sittypes[SITPI(fi)->Method];
  470.                   if(sithdr[SITFH_COMPDMETHOD]&SITprot)
  471.                   {
  472.                     fi->xfi_Flags |= XADFIF_CRYPTED;
  473.                     ai->xai_Flags |= XADAIF_CRYPTED;
  474.                   }
  475.  
  476.                   err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos+fi->xfi_CrunchSize, TAG_DONE);
  477.                 }
  478.                 else
  479.                 {
  480.                   xadFreeObjectA(fi, 0);
  481.                   err = XADERR_NOMEMORY;
  482.                 }
  483.               }
  484.               else
  485.                 err = XADERR_NOMEMORY;
  486.             }
  487.           }
  488.         }
  489.         else
  490.           err = XADERR_CHECKSUM;
  491.       }
  492.     }
  493.  
  494.     if(!err && ai->xai_InPos < fullsize)
  495.       err = XADERR_ILLEGALDATA;
  496.     if(err)
  497.     {
  498.       ai->xai_Flags |= XADAIF_FILECORRUPT;
  499.       ai->xai_LastError = err;
  500.     }
  501.   }
  502.  
  503. #ifdef DEBUG
  504.   if(err || (ai->xai_Flags & XADAIF_CRYPTED))
  505.     UnknownRequest(xadMasterBase, 0, ai->xai_InName);
  506. #endif
  507.  
  508.   return (ai->xai_FileInfo ? 0 : err);
  509. }
  510.  
  511. /*****************************************************************************/
  512.  
  513. #define SITESC  0x90    /* repeat packing escape */
  514.  
  515. static LONG SIT_rle(struct xadInOut *io)
  516. {
  517.   LONG ch, lastch = 0, n;
  518.  
  519.   while(!(io->xio_Flags & (XADIOF_LASTOUTBYTE|XADIOF_ERROR)))
  520.   {
  521.     if((ch = xadIOGetChar(io)) == SITESC)
  522.     {
  523.       if((n = xadIOGetChar(io) - 1) < 0)
  524.         lastch = xadIOPutChar(io, SITESC);
  525.       else
  526.         while(n--)
  527.           xadIOPutChar(io, lastch);
  528.     }
  529.     else
  530.       lastch = xadIOPutChar(io, ch);
  531.   }
  532.   return io->xio_Error;
  533. }
  534.  
  535. /*****************************************************************************/
  536.  
  537. #define UCOMPMAXCODE(n) (((ULONG) 1 << (n)) - 1)
  538. #define UCOMPBITS          16
  539. #define UCOMPSTACKSIZE   8000
  540. #define UCOMPFIRST        257           /* first free entry */
  541. #define UCOMPCLEAR        256           /* table clear output code */
  542. #define UCOMPINIT_BITS      9           /* initial number of bits/code */
  543. #define UCOMPBIT_MASK    0x1f
  544. #define UCOMPBLOCK_MASK  0x80
  545.  
  546. struct UCompData {
  547.   WORD          clear_flg;
  548.   UWORD         n_bits;                 /* number of bits/code */
  549.   UWORD         maxbits;                /* user settable max # bits/code */
  550.   ULONG         maxcode;                /* maximum code, given n_bits */
  551.   ULONG         maxmaxcode;
  552.   LONG          free_ent;
  553.   LONG          offset;
  554.   LONG          size;
  555.   UWORD *       tab_prefixof;
  556.   STRPTR        tab_suffixof;
  557.   UBYTE         stack[UCOMPSTACKSIZE];
  558.   UBYTE         buf[UCOMPBITS];
  559. };
  560.  
  561. /* Read one code from input. If EOF, return -1. */
  562. static LONG UCompgetcode(struct xadInOut *io, struct UCompData *cd)
  563. {
  564.   LONG code, r_off, bits;
  565.   UBYTE *bp = cd->buf;
  566.  
  567.   if(cd->clear_flg > 0 || cd->offset >= cd->size || cd->free_ent > cd->maxcode)
  568.   {
  569.     /*
  570.      * If the next entry will be too big for the current code
  571.      * size, then we must increase the size.  This implies reading
  572.      * a new buffer full, too.
  573.      */
  574.     if(cd->free_ent > cd->maxcode)
  575.     {
  576.       if(++cd->n_bits == cd->maxbits)
  577.         cd->maxcode = cd->maxmaxcode;   /* won't get any bigger now */
  578.       else
  579.         cd->maxcode = UCOMPMAXCODE(cd->n_bits);
  580.     }
  581.     if(cd->clear_flg > 0)
  582.     {
  583.       cd->maxcode = UCOMPMAXCODE(cd->n_bits = UCOMPINIT_BITS);
  584.       cd->clear_flg = 0;
  585.     }
  586.  
  587.     /* This reads maximum n_bits characters into buf */
  588.     cd->size = 0;
  589.     while(cd->size < cd->n_bits && !(io->xio_Flags & (XADIOF_LASTINBYTE|XADIOF_ERROR)))
  590.       cd->buf[cd->size++] = xadIOGetChar(io);
  591.     if(cd->size <= 0)
  592.       return -1;
  593.  
  594.     cd->offset = 0;
  595.     /* Round size down to integral number of codes */
  596.     cd->size = (cd->size << 3) - (cd->n_bits - 1);
  597.   }
  598.  
  599.   r_off = cd->offset;
  600.   bits = cd->n_bits;
  601.  
  602.   /* Get to the first byte. */
  603.   bp += (r_off >> 3);
  604.   r_off &= 7;
  605.  
  606.   /* Get first part (low order bits) */
  607.   code = (*bp++ >> r_off);
  608.   bits -= (8 - r_off);
  609.   r_off = 8 - r_off;                    /* now, offset into code word */
  610.  
  611.   /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
  612.   if(bits >= 8)
  613.   {
  614.     code |= *bp++ << r_off;
  615.     r_off += 8;
  616.     bits -= 8;
  617.   }
  618.  
  619.   /* high order bits. */
  620.   code |= (*bp & ((1<<bits)-1)) << r_off;
  621.   cd->offset += cd->n_bits;
  622.  
  623.   return code;
  624. }
  625.  
  626. /* Decompress. This routine adapts to the codes in the file building the
  627.  * "string" table on-the-fly; requiring no table to be stored in the
  628.  * compressed file.
  629.  */
  630. static LONG UCompDecomp(struct xadInOut *io, UBYTE bitinfo)
  631. {
  632.   LONG err = 0;
  633.   struct UCompData *cd;
  634.   struct xadMasterBase *xadMasterBase = io->xio_xadMasterBase;
  635.  
  636.   if((cd = (struct UCompData *) xadAllocVec(sizeof(struct UCompData), MEMF_CLEAR|MEMF_PUBLIC)))
  637.   {
  638.     LONG finchar, code, oldcode, incode, blockcomp;
  639.     STRPTR stackp, stack, stackend;
  640.  
  641.     stackp = stack = cd->stack;
  642.     stackend = stack+UCOMPSTACKSIZE;
  643.     cd->maxbits = bitinfo & UCOMPBIT_MASK;
  644.     blockcomp = bitinfo & UCOMPBLOCK_MASK;
  645.     cd->maxmaxcode = 1 << cd->maxbits;
  646.     cd->maxcode = UCOMPMAXCODE(cd->n_bits = UCOMPINIT_BITS);
  647.     cd->free_ent = blockcomp ? UCOMPFIRST : 256;
  648.     cd->clear_flg = cd->offset = cd->size = 0;
  649.  
  650.     if((cd->tab_prefixof = (UWORD *) xadAllocVec(sizeof(UWORD)*cd->maxmaxcode, MEMF_PUBLIC|MEMF_CLEAR)))
  651.     {
  652.       if((cd->tab_suffixof = (STRPTR) xadAllocVec(cd->maxmaxcode, MEMF_PUBLIC|MEMF_CLEAR)))
  653.       {
  654.         /* Initialize the first 256 entries in the table. */
  655.         for(code = 255; code >= 0; code--)
  656.         {
  657. //        cd->tab_prefixof[code] = 0;
  658.           cd->tab_suffixof[code] = (UBYTE) code;
  659.         }
  660.  
  661.         if((finchar = oldcode = UCompgetcode(io, cd)) == -1)
  662.           err = XADERR_DECRUNCH;
  663.         else
  664.         {
  665.           xadIOPutChar(io, finchar); /* first code must be 8 bits = UBYTE */
  666.  
  667.           while((code = UCompgetcode(io, cd)) > -1)
  668.           {
  669.             if((code == UCOMPCLEAR) && blockcomp)
  670.             {
  671.               for(code = 255; code >= 0; code--)
  672.                 cd->tab_prefixof[code] = 0;
  673.               cd->clear_flg = 1;
  674.               cd->free_ent = UCOMPFIRST - 1;
  675.               if((code = UCompgetcode(io, cd)) == -1)
  676.                 break;                                  /* O, untimely death! */
  677.             }
  678.             incode = code;
  679.  
  680.             /* Special case for KwKwK string. */
  681.             if(code >= cd->free_ent)
  682.             {
  683.               *stackp++ = finchar;
  684.               code = oldcode;
  685.             }
  686.  
  687.             /* Generate output characters in reverse order */
  688.             while(stackp < stackend && code >= 256)
  689.             {
  690.               *stackp++ = cd->tab_suffixof[code];
  691.               code = cd->tab_prefixof[code];
  692.             }
  693.             if(stackp >= stackend)
  694.             {
  695.               err = XADERR_ILLEGALDATA;
  696.               break;
  697.             }
  698.             *(stackp++) = finchar = cd->tab_suffixof[code];
  699.  
  700.             /* And put them out in forward order */
  701.             do
  702.             {
  703.               xadIOPutChar(io, *(--stackp));
  704.             } while(stackp > stack);
  705.  
  706.             /* Generate the new entry. */
  707.             if((code = cd->free_ent) < cd->maxmaxcode)
  708.             {
  709.               cd->tab_prefixof[code] = (UWORD) oldcode;
  710.               cd->tab_suffixof[code] = finchar;
  711.               cd->free_ent = code+1;
  712.             }
  713.             /* Remember previous code. */
  714.             oldcode = incode;
  715.           }
  716.           if(!err)
  717.             err = io->xio_Error;
  718.         }
  719.         xadFreeObjectA(cd->tab_suffixof, 0);
  720.       }
  721.       else
  722.         err = XADERR_NOMEMORY;
  723.       xadFreeObjectA(cd->tab_prefixof, 0);
  724.     }
  725.     else
  726.       err = XADERR_NOMEMORY;
  727.     xadFreeObjectA(cd, 0);
  728.   }
  729.   else
  730.     err = XADERR_NOMEMORY;
  731.  
  732.   return err;
  733. }
  734.  
  735. /*****************************************************************************/
  736.  
  737. struct sithufnode {
  738.   struct sithufnode *one;
  739.   struct sithufnode *zero;
  740.   UBYTE              byte;
  741. };
  742.  
  743. static LONG SIT_huffman(struct xadInOut *io)
  744. {
  745.   struct sithufnode *np, *npb, *nodelist;
  746.   LONG numfreetree = 0; /* number of free np->one nodes */
  747.   struct xadMasterBase *xadMasterBase = io->xio_xadMasterBase;
  748.  
  749.    /* 515 because StuffIt Classic needs more than the needed 511 */
  750.   if((nodelist = (struct sithufnode *) xadAllocVec(sizeof(struct sithufnode)*515, MEMF_ANY|MEMF_CLEAR)))
  751.   {
  752.     npb = nodelist;
  753.     do /* removed recursion, optimized a lot */
  754.     {
  755.       do
  756.       {
  757.         np = npb++;
  758.         if(xadIOGetBitsHigh(io, 1))
  759.         {
  760.           np->byte = xadIOGetBitsHigh(io, 8);
  761.           np->zero = np->one = (struct sithufnode *) -1;
  762.         }
  763.         else
  764.         {
  765.           np->zero = npb;
  766.           ++numfreetree;
  767.         }
  768.       } while(!np->one);
  769.       if(numfreetree--)
  770.       {
  771.         while(np->one)
  772.           --np;
  773.         np->one = npb;
  774.       }
  775.     } while(numfreetree >= 0);
  776.  
  777.     while(!(io->xio_Flags & (XADIOF_LASTOUTBYTE|XADIOF_ERROR)))
  778.     {
  779.       np = nodelist;
  780.       while(np->one != (struct sithufnode *) -1)
  781.         np = xadIOGetBitsHigh(io, 1) ? np->one : np->zero;
  782.       xadIOPutChar(io, np->byte);
  783.     }
  784.  
  785.     xadFreeObjectA(nodelist, 0);
  786.   }
  787.   else
  788.     return XADERR_NOMEMORY;
  789.  
  790.   return io->xio_Error;
  791. }
  792.  
  793. /*****************************************************************************/
  794.  
  795. /* Note: compare with LZSS decoding in lharc! */
  796. #define SITLZAH_N       314
  797. #define SITLZAH_T       (2*SITLZAH_N-1)
  798. /*      Huffman table used for first 6 bits of offset:
  799.         #bits   codes
  800.         3       0x000
  801.         4       0x040-0x080
  802.         5       0x100-0x2c0
  803.         6       0x300-0x5c0
  804.         7       0x600-0xbc0
  805.         8       0xc00-0xfc0
  806. */
  807.  
  808. static UBYTE SITLZAH_HuffCode[] = {
  809.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  810.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  811.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  812.   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  813.   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  814.   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  815.   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  816.   0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  817.   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  818.   0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
  819.   0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  820.   0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
  821.   0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
  822.   0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
  823.   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  824.   0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
  825.   0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
  826.   0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
  827.   0x30, 0x30, 0x30, 0x30, 0x34, 0x34, 0x34, 0x34,
  828.   0x38, 0x38, 0x38, 0x38, 0x3c, 0x3c, 0x3c, 0x3c,
  829.   0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x44, 0x44,
  830.   0x48, 0x48, 0x48, 0x48, 0x4c, 0x4c, 0x4c, 0x4c,
  831.   0x50, 0x50, 0x50, 0x50, 0x54, 0x54, 0x54, 0x54,
  832.   0x58, 0x58, 0x58, 0x58, 0x5c, 0x5c, 0x5c, 0x5c,
  833.   0x60, 0x60, 0x64, 0x64, 0x68, 0x68, 0x6c, 0x6c,
  834.   0x70, 0x70, 0x74, 0x74, 0x78, 0x78, 0x7c, 0x7c,
  835.   0x80, 0x80, 0x84, 0x84, 0x88, 0x88, 0x8c, 0x8c,
  836.   0x90, 0x90, 0x94, 0x94, 0x98, 0x98, 0x9c, 0x9c,
  837.   0xa0, 0xa0, 0xa4, 0xa4, 0xa8, 0xa8, 0xac, 0xac,
  838.   0xb0, 0xb0, 0xb4, 0xb4, 0xb8, 0xb8, 0xbc, 0xbc,
  839.   0xc0, 0xc4, 0xc8, 0xcc, 0xd0, 0xd4, 0xd8, 0xdc,
  840.   0xe0, 0xe4, 0xe8, 0xec, 0xf0, 0xf4, 0xf8, 0xfc};
  841.  
  842. static UBYTE SITLZAH_HuffLength[] = {
  843.     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  844.     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  845.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  846.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  847.     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  848.     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  849.     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  850.     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  851.     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  852.     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  853.     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  854.     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  855.     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  856.     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  857.     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  858.     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
  859.  
  860. struct SITLZAHData {
  861.   UBYTE buf[4096];
  862.   ULONG Frequ[1000];
  863.   ULONG ForwTree[1000];
  864.   ULONG BackTree[1000];
  865. };
  866.  
  867. static void SITLZAH_move(ULONG *p, ULONG *q, ULONG n)
  868. {
  869.   if(p > q)
  870.   {
  871.     while(n-- > 0)
  872.       *q++ = *p++;
  873.   }
  874.   else
  875.   {
  876.     p += n;
  877.     q += n;
  878.     while(n-- > 0)
  879.       *--q = *--p;
  880.   }
  881. }
  882.  
  883. static LONG SIT_lzah(struct xadInOut *io)
  884. {
  885.   LONG i, i1, j, k, l, ch, byte, offs, skip;
  886.   ULONG bufptr = 0;
  887.   struct SITLZAHData *dat;
  888.   struct xadMasterBase *xadMasterBase = io->xio_xadMasterBase;
  889.  
  890.   if((dat = (struct SITLZAHData *) xadAllocVec(sizeof(struct SITLZAHData), MEMF_CLEAR|MEMF_PUBLIC)))
  891.   {
  892.     /* init buffer */
  893.     for(i = 0; i < SITLZAH_N; i++)
  894.     {
  895.       dat->Frequ[i] = 1;
  896.       dat->ForwTree[i] = i + SITLZAH_T;
  897.       dat->BackTree[i + SITLZAH_T] = i;
  898.     }
  899.     for(i = 0, j = SITLZAH_N; j < SITLZAH_T; i += 2, j++)
  900.     {
  901.       dat->Frequ[j] = dat->Frequ[i] + dat->Frequ[i + 1];
  902.       dat->ForwTree[j] = i;
  903.       dat->BackTree[i] = j;
  904.       dat->BackTree[i + 1] = j;
  905.     }
  906.     dat->Frequ[SITLZAH_T] = 0xffff;
  907.     dat->BackTree[SITLZAH_T - 1] = 0;
  908.  
  909.     for(i = 0; i < 4096; i++)
  910.       dat->buf[i] = ' ';
  911.  
  912.     while(!(io->xio_Flags & (XADIOF_LASTOUTBYTE|XADIOF_ERROR)))
  913.     {
  914.       ch = dat->ForwTree[SITLZAH_T - 1];
  915.       while(ch < SITLZAH_T)
  916.         ch = dat->ForwTree[ch + xadIOGetBitsHigh(io, 1)];
  917.       ch -= SITLZAH_T;
  918.       if(dat->Frequ[SITLZAH_T - 1] >= 0x8000) /* need to reorder */
  919.       {
  920.         j = 0;
  921.         for(i = 0; i < SITLZAH_T; i++)
  922.         {
  923.           if(dat->ForwTree[i] >= SITLZAH_T)
  924.           {
  925.             dat->Frequ[j] = ((dat->Frequ[i] + 1) >> 1);
  926.             dat->ForwTree[j] = dat->ForwTree[i];
  927.             j++;
  928.           }
  929.         }
  930.         j = SITLZAH_N;
  931.         for(i = 0; i < SITLZAH_T; i += 2)
  932.         {
  933.           k = i + 1;
  934.           l = dat->Frequ[i] + dat->Frequ[k];
  935.           dat->Frequ[j] = l;
  936.           k = j - 1;
  937.           while(l < dat->Frequ[k])
  938.             k--;
  939.           k = k + 1;
  940.           SITLZAH_move(dat->Frequ + k, dat->Frequ + k + 1, j - k);
  941.           dat->Frequ[k] = l;
  942.           SITLZAH_move(dat->ForwTree + k, dat->ForwTree + k + 1, j - k);
  943.           dat->ForwTree[k] = i;
  944.           j++;
  945.         }
  946.         for(i = 0; i < SITLZAH_T; i++)
  947.         {
  948.           k = dat->ForwTree[i];
  949.           if(k >= SITLZAH_T)
  950.             dat->BackTree[k] = i;
  951.           else
  952.           {
  953.             dat->BackTree[k] = i;
  954.             dat->BackTree[k + 1] = i;
  955.           }
  956.         }
  957.       }
  958.  
  959.       i = dat->BackTree[ch + SITLZAH_T];
  960.       do
  961.       {
  962.         j = ++dat->Frequ[i];
  963.         i1 = i + 1;
  964.         if(dat->Frequ[i1] < j)
  965.         {
  966.           while(dat->Frequ[++i1] < j)
  967.             ;
  968.           i1--;
  969.           dat->Frequ[i] = dat->Frequ[i1];
  970.           dat->Frequ[i1] = j;
  971.  
  972.           j = dat->ForwTree[i];
  973.           dat->BackTree[j] = i1;
  974.           if(j < SITLZAH_T)
  975.             dat->BackTree[j + 1] = i1;
  976.           dat->ForwTree[i] = dat->ForwTree[i1];
  977.           dat->ForwTree[i1] = j;
  978.           j = dat->ForwTree[i];
  979.           dat->BackTree[j] = i;
  980.           if(j < SITLZAH_T)
  981.             dat->BackTree[j + 1] = i;
  982.           i = i1;
  983.         }
  984.         i = dat->BackTree[i];
  985.       } while(i != 0);
  986.  
  987.       if(ch < 256)
  988.       {
  989.         dat->buf[bufptr++] = xadIOPutChar(io, ch);
  990.         bufptr &= 0xFFF;
  991.       }
  992.       else
  993.       {
  994.         byte = xadIOGetBitsHigh(io, 8);
  995.         skip = SITLZAH_HuffLength[byte] - 2;
  996.         offs = (SITLZAH_HuffCode[byte]<<4) | (((byte << skip)  + xadIOGetBitsHigh(io, skip)) & 0x3f);
  997.         offs = ((bufptr - offs - 1) & 0xfff);
  998.         ch = ch - 253;
  999.         while(ch-- > 0)
  1000.         {
  1001.           dat->buf[bufptr++] = xadIOPutChar(io, dat->buf[offs++ & 0xfff]);
  1002.           bufptr &= 0xFFF;
  1003.         }
  1004.       }
  1005.     }
  1006.     xadFreeObjectA(dat, 0);
  1007.   }
  1008.   else
  1009.     return XADERR_NOMEMORY;
  1010.  
  1011.   return io->xio_Error;
  1012. }
  1013.  
  1014. /*****************************************************************************/
  1015.  
  1016. struct SITMWData {
  1017.   UWORD dict[16385];
  1018.   UWORD stack[16384];
  1019. };
  1020.  
  1021. static void SITMW_out(struct xadInOut *io, struct SITMWData *dat, LONG ptr)
  1022. {
  1023.   UWORD stack_ptr = 1;
  1024.  
  1025.   dat->stack[0] = ptr;
  1026.   while(stack_ptr)
  1027.   {
  1028.     ptr = dat->stack[--stack_ptr];
  1029.     while(ptr >= 256)
  1030.     {
  1031.       dat->stack[stack_ptr++] = dat->dict[ptr];
  1032.       ptr = dat->dict[ptr - 1];
  1033.     }
  1034.     xadIOPutChar(io, (UBYTE) ptr);
  1035.   }
  1036. }
  1037.  
  1038. static LONG SIT_mw(struct xadInOut *io)
  1039. {
  1040.   struct SITMWData *dat;
  1041.   struct xadMasterBase *xadMasterBase = io->xio_xadMasterBase;
  1042.  
  1043.   if((dat = (struct SITMWData *) xadAllocVec(sizeof(struct SITMWData), MEMF_CLEAR|MEMF_PUBLIC)))
  1044.   {
  1045.     LONG ptr, max, max1, bits;
  1046.  
  1047.     while(!(io->xio_Flags & (XADIOF_LASTOUTBYTE|XADIOF_ERROR)))
  1048.     {
  1049.       max = 256;
  1050.       max1 = max << 1;
  1051.       bits = 9;
  1052.       ptr = xadIOGetBitsLow(io, bits);
  1053.       if(ptr < max)
  1054.       {
  1055.         dat->dict[255] = ptr;
  1056.         SITMW_out(io, dat, ptr);
  1057.         while(!(io->xio_Flags & (XADIOF_LASTOUTBYTE|XADIOF_ERROR)) &&
  1058.         (ptr = xadIOGetBitsLow(io, bits)) < max)
  1059.         {
  1060.           dat->dict[max++] = ptr;
  1061.           if(max == max1)
  1062.           {
  1063.             max1 <<= 1;
  1064.             bits++;
  1065.           }
  1066.           SITMW_out(io, dat, ptr);
  1067.         }
  1068.       }
  1069.       if(ptr > max)
  1070.         break;
  1071.     }
  1072.  
  1073.     xadFreeObjectA(dat, 0);
  1074.   }
  1075.   else
  1076.     return XADERR_NOMEMORY;
  1077.  
  1078.   return io->xio_Error;
  1079. }
  1080.  
  1081. /*****************************************************************************/
  1082.  
  1083. struct SIT13Buffer {
  1084.   UWORD data;
  1085.   BYTE  bits;
  1086. };
  1087.  
  1088. struct SIT13Store {
  1089.   WORD  freq;
  1090.   UWORD d1;
  1091.   UWORD d2;
  1092. };
  1093.  
  1094. struct SIT13Data {
  1095.   UWORD              MaxBits;
  1096.   struct SIT13Store  Buffer4[0xE08];
  1097.   struct SIT13Buffer Buffer1[0x1000];
  1098.   struct SIT13Buffer Buffer2[0x1000];
  1099.   struct SIT13Buffer Buffer3[0x1000];
  1100.   struct SIT13Buffer Buffer3b[0x1000];
  1101.   struct SIT13Buffer Buffer5[0x141];
  1102.   UBYTE              TextBuf[658];
  1103.   UBYTE              Window[0x10000];
  1104. };
  1105.  
  1106. static const UBYTE SIT13Bits[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
  1107. static const UWORD SIT13Info[37] = {
  1108.   0x5D8, 0x058, 0x040, 0x0C0, 0x000, 0x078, 0x02B, 0x014,
  1109.   0x00C, 0x01C, 0x01B, 0x00B, 0x010, 0x020, 0x038, 0x018,
  1110.   0x0D8, 0xBD8, 0x180, 0x680, 0x380, 0xF80, 0x780, 0x480,
  1111.   0x080, 0x280, 0x3D8, 0xFD8, 0x7D8, 0x9D8, 0x1D8, 0x004,
  1112.   0x001, 0x002, 0x007, 0x003, 0x008
  1113. };
  1114. static const UWORD SIT13InfoBits[37] = {
  1115.   11,  8,  8,  8,  8,  7,  6,  5,  5,  5,  5,  6,  5,  6,  7,  7,
  1116.    9, 12, 10, 11, 11, 12, 12, 11, 11, 11, 12, 12, 12, 12, 12,  5,
  1117.    2,  2,  3,  4,  5
  1118. };
  1119. static const UWORD SIT13StaticPos[5] = {0, 330, 661, 991, 1323};
  1120. static const UBYTE SIT13StaticBits[5] = {11, 13, 14, 11, 11};
  1121. static const UBYTE SIT13Static[1655] = {
  1122.   0xB8,0x98,0x78,0x77,0x75,0x97,0x76,0x87,0x77,0x77,0x77,0x78,0x67,0x87,0x68,0x67,0x3B,0x77,0x78,0x67,
  1123.   0x77,0x77,0x77,0x59,0x76,0x87,0x77,0x77,0x77,0x77,0x77,0x77,0x76,0x87,0x67,0x87,0x77,0x77,0x75,0x88,
  1124.   0x59,0x75,0x79,0x77,0x78,0x68,0x77,0x67,0x73,0xB6,0x65,0xB6,0x76,0x97,0x67,0x47,0x9A,0x2A,0x4A,0x87,
  1125.   0x77,0x78,0x67,0x86,0x78,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
  1126.   0x68,0x77,0x77,0x77,0x67,0x87,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x68,0x77,0x77,0x68,0x77,0x77,0x77,
  1127.   0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,0x77,0x67,0x87,
  1128.   0x68,0x77,0x77,0x77,0x68,0x77,0x68,0x63,0x86,0x7A,0x87,0x77,0x77,0x87,0x76,0x87,0x77,0x77,0x77,0x77,
  1129.   0x77,0x77,0x77,0x77,0x77,0x76,0x86,0x77,0x86,0x86,0x86,0x86,0x87,0x76,0x86,0x87,0x67,0x74,0xA7,0x86,
  1130.   0x36,0x88,0x78,0x76,0x87,0x76,0x96,0x87,0x77,0x84,0xA6,0x86,0x87,0x76,0x92,0xB5,0x94,0xA6,0x96,0x85,
  1131.   0x78,0x75,0x96,0x86,0x86,0x75,0xA7,0x67,0x87,0x85,0x87,0x85,0x95,0x77,0x77,0x85,0xA3,0xA7,0x93,0x87,
  1132.   0x86,0x94,0x85,0xA8,0x67,0x85,0xA5,0x95,0x86,0x68,0x67,0x77,0x96,0x78,0x75,0x86,0x77,0xA5,0x67,0x87,
  1133.   0x85,0xA6,0x75,0x96,0x85,0x87,0x95,0x95,0x87,0x86,0x94,0xA5,0x86,0x85,0x87,0x86,0x86,0x86,0x86,0x77,
  1134.   0x67,0x76,0x66,0x9A,0x75,0xA5,0x94,0x97,0x76,0x96,0x76,0x95,0x86,0x77,0x86,0x87,0x75,0xA5,0x96,0x85,
  1135.   0x86,0x96,0x86,0x86,0x85,0x96,0x86,0x76,0x95,0x86,0x95,0x95,0x95,0x87,0x76,0x87,0x76,0x96,0x85,0x78,
  1136.   0x75,0xA6,0x85,0x86,0x95,0x86,0x95,0x86,0x45,0x69,0x78,0x77,0x87,0x67,0x69,0x58,0x79,0x68,0x78,0x87,
  1137.   0x78,0x66,0x88,0x68,0x68,0x77,0x76,0x87,0x68,0x68,0x69,0x58,0x5A,0x4B,0x76,0x88,0x69,0x67,0xA7,0x70,
  1138.   0x9F,0x90,0xA4,0x84,0x77,0x77,0x77,0x89,0x17,0x77,0x7B,0xA7,0x86,0x87,0x77,0x68,0x68,0x69,0x67,0x78,
  1139.   0x77,0x78,0x76,0x87,0x77,0x76,0x73,0xB6,0x87,0x96,0x66,0x87,0x76,0x85,0x87,0x78,0x77,0x77,0x86,0x77,
  1140.   0x86,0x78,0x66,0x76,0x77,0x87,0x86,0x78,0x76,0x76,0x86,0xA5,0x67,0x97,0x77,0x87,0x87,0x76,0x66,0x59,
  1141.   0x67,0x59,0x77,0x6A,0x65,0x86,0x78,0x94,0x77,0x88,0x77,0x78,0x86,0x86,0x76,0x88,0x76,0x87,0x67,0x87,
  1142.   0x77,0x77,0x76,0x87,0x86,0x77,0x77,0x77,0x86,0x86,0x76,0x96,0x77,0x77,0x76,0x78,0x86,0x86,0x86,0x95,
  1143.   0x86,0x96,0x85,0x95,0x86,0x87,0x75,0x88,0x77,0x87,0x57,0x78,0x76,0x86,0x76,0x96,0x86,0x87,0x76,0x87,
  1144.   0x86,0x76,0x77,0x86,0x78,0x78,0x57,0x87,0x86,0x76,0x85,0xA5,0x87,0x76,0x86,0x86,0x85,0x86,0x53,0x98,
  1145.   0x78,0x78,0x77,0x87,0x79,0x67,0x79,0x85,0x87,0x69,0x67,0x68,0x78,0x69,0x68,0x69,0x58,0x87,0x66,0x97,
  1146.   0x68,0x68,0x76,0x85,0x78,0x87,0x67,0x97,0x67,0x74,0xA2,0x28,0x77,0x78,0x77,0x77,0x78,0x68,0x67,0x78,
  1147.   0x77,0x78,0x68,0x68,0x77,0x59,0x67,0x5A,0x68,0x68,0x68,0x68,0x68,0x68,0x67,0x77,0x78,0x68,0x68,0x78,
  1148.   0x59,0x58,0x76,0x77,0x68,0x78,0x68,0x59,0x69,0x58,0x68,0x68,0x67,0x78,0x77,0x78,0x69,0x58,0x68,0x57,
  1149.   0x78,0x67,0x78,0x76,0x88,0x58,0x67,0x7A,0x46,0x88,0x77,0x78,0x68,0x68,0x66,0x78,0x78,0x68,0x68,0x59,
  1150.   0x68,0x69,0x68,0x59,0x67,0x78,0x59,0x58,0x69,0x59,0x67,0x68,0x67,0x69,0x69,0x57,0x79,0x68,0x59,0x59,
  1151.   0x59,0x68,0x68,0x68,0x58,0x78,0x67,0x59,0x68,0x78,0x59,0x58,0x78,0x58,0x76,0x78,0x68,0x68,0x68,0x69,
  1152.   0x59,0x67,0x68,0x69,0x59,0x59,0x58,0x69,0x59,0x59,0x58,0x5A,0x58,0x68,0x68,0x59,0x58,0x68,0x66,0x47,
  1153.   0x88,0x77,0x87,0x77,0x87,0x76,0x87,0x87,0x87,0x77,0x77,0x87,0x67,0x96,0x78,0x76,0x87,0x68,0x77,0x77,
  1154.   0x76,0x86,0x96,0x86,0x88,0x77,0x85,0x86,0x8B,0x76,0x0A,0xF9,0x07,0x38,0x57,0x67,0x77,0x78,0x77,0x91,
  1155.   0x77,0xD7,0x77,0x7A,0x67,0x3C,0x68,0x68,0x77,0x68,0x78,0x59,0x77,0x68,0x77,0x68,0x76,0x77,0x69,0x68,
  1156.   0x68,0x68,0x68,0x67,0x68,0x68,0x77,0x87,0x77,0x67,0x78,0x68,0x67,0x58,0x78,0x68,0x77,0x68,0x78,0x67,
  1157.   0x68,0x68,0x67,0x78,0x77,0x77,0x87,0x77,0x76,0x67,0x86,0x85,0x87,0x86,0x97,0x58,0x67,0x79,0x57,0x77,
  1158.   0x87,0x77,0x87,0x77,0x76,0x59,0x78,0x77,0x77,0x68,0x77,0x77,0x76,0x78,0x77,0x77,0x77,0x76,0x87,0x77,
  1159.   0x77,0x68,0x77,0x77,0x77,0x67,0x78,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x68,0x77,0x76,0x68,0x87,0x77,
  1160.   0x77,0x77,0x77,0x68,0x77,0x68,0x77,0x77,0x77,0x77,0x77,0x77,0x76,0x78,0x77,0x77,0x76,0x87,0x77,0x77,
  1161.   0x67,0x78,0x77,0x77,0x76,0x78,0x67,0x68,0x68,0x29,0x77,0x88,0x78,0x78,0x77,0x68,0x77,0x77,0x77,0x77,
  1162.   0x77,0x77,0x77,0x77,0x4A,0x77,0x4A,0x74,0x77,0x77,0x68,0xA4,0x7A,0x47,0x76,0x86,0x78,0x76,0x7A,0x4A,
  1163.   0x83,0xB2,0x87,0x77,0x87,0x76,0x96,0x86,0x96,0x76,0x78,0x87,0x77,0x85,0x87,0x85,0x96,0x65,0xB5,0x95,
  1164.   0x96,0x77,0x77,0x86,0x76,0x86,0x86,0x87,0x86,0x86,0x76,0x96,0x96,0x57,0x77,0x85,0x97,0x85,0x86,0xA5,
  1165.   0x86,0x85,0x87,0x77,0x68,0x78,0x77,0x95,0x86,0x75,0x87,0x76,0x86,0x79,0x68,0x84,0x96,0x76,0xB3,0x87,
  1166.   0x77,0x68,0x86,0xA5,0x77,0x56,0xB6,0x68,0x85,0x93,0xB6,0x95,0x95,0x85,0x95,0xA5,0x95,0x95,0x69,0x85,
  1167.   0x95,0x85,0x86,0x86,0x97,0x84,0x85,0xB6,0x84,0xA5,0x95,0xA4,0x95,0x95,0x95,0x68,0x95,0x66,0xA6,0x95,
  1168.   0x95,0x95,0x86,0x93,0xB5,0x86,0x77,0x94,0x96,0x95,0x96,0x85,0x68,0x94,0x87,0x95,0x86,0x86,0x93,0xB4,
  1169.   0xA3,0xB3,0xA6,0x86,0x85,0x85,0x96,0x76,0x86,0x64,0x69,0x78,0x68,0x78,0x78,0x77,0x67,0x79,0x68,0x79,
  1170.   0x59,0x56,0x87,0x98,0x68,0x78,0x76,0x88,0x68,0x68,0x67,0x76,0x87,0x68,0x78,0x76,0x78,0x77,0x78,0xA6,
  1171.   0x80,0xAF,0x81,0x38,0x47,0x67,0x77,0x78,0x77,0x89,0x07,0x79,0xB7,0x87,0x86,0x86,0x87,0x86,0x87,0x76,
  1172.   0x78,0x77,0x87,0x66,0x96,0x86,0x86,0x74,0xA6,0x87,0x86,0x77,0x86,0x77,0x76,0x77,0x77,0x87,0x77,0x77,
  1173.   0x77,0x77,0x87,0x65,0x78,0x77,0x78,0x75,0x88,0x85,0x76,0x87,0x95,0x77,0x86,0x87,0x86,0x96,0x85,0x76,
  1174.   0x69,0x67,0x59,0x77,0x6A,0x65,0x86,0x78,0x94,0x77,0x88,0x77,0x78,0x85,0x96,0x65,0x98,0x77,0x87,0x67,
  1175.   0x86,0x77,0x87,0x66,0x87,0x86,0x86,0x86,0x77,0x86,0x86,0x76,0x87,0x86,0x77,0x76,0x87,0x77,0x86,0x86,
  1176.   0x86,0x87,0x76,0x95,0x86,0x86,0x87,0x65,0x97,0x86,0x87,0x76,0x86,0x86,0x87,0x75,0x88,0x76,0x87,0x76,
  1177.   0x87,0x76,0x77,0x77,0x86,0x78,0x76,0x76,0x96,0x78,0x76,0x77,0x86,0x77,0x77,0x76,0x96,0x75,0x95,0x56,
  1178.   0x87,0x87,0x87,0x78,0x88,0x67,0x87,0x87,0x58,0x87,0x77,0x87,0x77,0x76,0x87,0x96,0x59,0x88,0x37,0x89,
  1179.   0x69,0x69,0x84,0x96,0x67,0x77,0x57,0x4B,0x58,0xB7,0x80,0x8E,0x0D,0x78,0x87,0x77,0x87,0x68,0x79,0x49,
  1180.   0x76,0x78,0x77,0x5A,0x67,0x69,0x68,0x68,0x68,0x4A,0x68,0x69,0x67,0x69,0x59,0x58,0x68,0x67,0x69,0x77,
  1181.   0x77,0x69,0x68,0x68,0x66,0x68,0x87,0x68,0x77,0x5A,0x68,0x67,0x68,0x68,0x67,0x78,0x78,0x67,0x6A,0x59,
  1182.   0x67,0x57,0x95,0x78,0x77,0x86,0x88,0x57,0x77,0x68,0x67,0x79,0x76,0x76,0x98,0x68,0x75,0x68,0x88,0x58,
  1183.   0x87,0x5A,0x57,0x79,0x67,0x59,0x78,0x49,0x58,0x77,0x79,0x49,0x68,0x59,0x77,0x68,0x78,0x48,0x79,0x67,
  1184.   0x68,0x59,0x68,0x68,0x59,0x75,0x6A,0x68,0x76,0x4C,0x67,0x77,0x78,0x59,0x69,0x56,0x96,0x68,0x68,0x68,
  1185.   0x77,0x69,0x67,0x68,0x67,0x78,0x69,0x68,0x58,0x59,0x68,0x68,0x69,0x49,0x77,0x59,0x67,0x69,0x67,0x68,
  1186.   0x65,0x48,0x77,0x87,0x86,0x96,0x88,0x75,0x87,0x96,0x87,0x95,0x87,0x77,0x68,0x86,0x77,0x77,0x96,0x68,
  1187.   0x86,0x77,0x85,0x5A,0x81,0xD5,0x95,0x68,0x99,0x74,0x98,0x77,0x09,0xF9,0x0A,0x5A,0x66,0x58,0x77,0x87,
  1188.   0x91,0x77,0x77,0xE9,0x77,0x77,0x77,0x76,0x87,0x75,0x97,0x77,0x77,0x77,0x78,0x68,0x68,0x68,0x67,0x3B,
  1189.   0x59,0x77,0x77,0x57,0x79,0x57,0x86,0x87,0x67,0x97,0x77,0x57,0x79,0x77,0x77,0x75,0x95,0x77,0x79,0x75,
  1190.   0x97,0x57,0x77,0x79,0x58,0x69,0x77,0x77,0x77,0x77,0x77,0x75,0x86,0x77,0x87,0x58,0x95,0x78,0x65,0x8A,
  1191.   0x39,0x58,0x87,0x96,0x87,0x77,0x77,0x77,0x86,0x87,0x76,0x78,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,
  1192.   0x77,0x68,0x77,0x68,0x77,0x67,0x86,0x77,0x78,0x77,0x77,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,0x68,
  1193.   0x77,0x68,0x77,0x67,0x78,0x77,0x77,0x68,0x68,0x76,0x87,0x68,0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x77,
  1194.   0x77,0x77,0x77,0x68,0x77,0x77,0x77,0x68,0x68,0x68,0x76,0x38,0x97,0x67,0x79,0x77,0x77,0x77,0x77,0x77,
  1195.   0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x78,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x68,
  1196.   0x72,0xC5,0x86,0x86,0x98,0x77,0x86,0x78,0x1C,0x85,0x2E,0x77,0x77,0x77,0x87,0x86,0x76,0x86,0x86,0xA0,
  1197.   0xBD,0x49,0x97,0x66,0x48,0x88,0x48,0x68,0x86,0x78,0x77,0x77,0x78,0x66,0xA6,0x87,0x83,0x85,0x88,0x78,
  1198.   0x66,0xA7,0x56,0x87,0x6A,0x46,0x89,0x76,0xA7,0x76,0x87,0x74,0xA2,0x86,0x77,0x79,0x66,0xB6,0x48,0x67,
  1199.   0x8A,0x36,0x88,0x77,0xA5,0xA5,0xB1,0xE9,0x39,0x78,0x78,0x75,0x87,0x77,0x77,0x77,0x68,0x58,0x79,0x69,
  1200.   0x4A,0x59,0x29,0x6A,0x3C,0x3B,0x46,0x78,0x75,0x89,0x76,0x89,0x4A,0x56,0x88,0x3B,0x66,0x88,0x68,0x87,
  1201.   0x57,0x97,0x38,0x87,0x56,0xB7,0x84,0x88,0x67,0x57,0x95,0xA8,0x59,0x77,0x68,0x4A,0x49,0x69,0x57,0x6A,
  1202.   0x59,0x58,0x67,0x87,0x5A,0x75,0x78,0x69,0x56,0x97,0x77,0x73,0x08,0x78,0x78,0x77,0x87,0x78,0x77,0x78,
  1203.   0x77,0x77,0x87,0x78,0x68,0x77,0x77,0x87,0x78,0x76,0x86,0x97,0x58,0x77,0x78,0x58,0x78,0x77,0x68,0x78,
  1204.   0x75,0x95,0xB7,0x70,0x8F,0x80,0xA6,0x87,0x65,0x66,0x78,0x7A,0x17,0x77,0x70,
  1205. };
  1206.  
  1207. static void SIT13_Func1(struct SIT13Data *s, struct SIT13Buffer *buf, ULONG info, UWORD bits, UWORD num)
  1208. {
  1209.   ULONG i, j;
  1210.  
  1211.   if(bits <= 12)
  1212.   {
  1213.     for(i = 0; i < (1<<12); i += (1<<bits))
  1214.     {
  1215.       buf[info+i].data = num;
  1216.       buf[info+i].bits = bits;
  1217.     }
  1218.   }
  1219.   else
  1220.   {
  1221.     j = bits-12;
  1222.  
  1223.     if(buf[info & 0xFFF].bits != 0x1F)
  1224.     {
  1225.       buf[info & 0xFFF].bits = 0x1F;
  1226.       buf[info & 0xFFF].data = s->MaxBits++;
  1227.     }
  1228.     bits = buf[info & 0xFFF].data;
  1229.     info >>= 12;
  1230.  
  1231.     while(j--)
  1232.     {
  1233.       UWORD *a;
  1234.  
  1235.       a = info & 1 ? &s->Buffer4[bits].d2 : &s->Buffer4[bits].d1;
  1236.       if(!*a)
  1237.         *a = s->MaxBits++;
  1238.       bits = *a;
  1239.       info >>= 1;
  1240.     }
  1241.     s->Buffer4[bits].freq = num;
  1242.   }
  1243. }
  1244.  
  1245. static void SIT13_SortTree(struct SIT13Data *s, struct SIT13Buffer *buf, struct SIT13Buffer *buf2)
  1246. {
  1247.   UWORD td;
  1248.   BYTE tb;
  1249.  
  1250.   struct SIT13Buffer *a, *b;
  1251.  
  1252.   while(buf2-1 > buf)
  1253.   {
  1254.     a = buf;
  1255.     b = buf2;
  1256.  
  1257.     for(;;)
  1258.     {
  1259.       while(++a < buf2)
  1260.       {
  1261.         tb = a->bits - buf->bits;
  1262.         if(tb > 0 || (!tb && (a->data >= buf->data)))
  1263.           break;
  1264.       }
  1265.       while(--b > buf)
  1266.       {
  1267.         tb = b->bits - buf->bits;
  1268.         if(tb < 0 || (!tb && (b->data <= buf->data)))
  1269.           break;
  1270.       }
  1271.       if(b < a)
  1272.         break;
  1273.       else
  1274.       {
  1275.         tb = a->bits;
  1276.         td = a->data;
  1277.         a->bits = b->bits;
  1278.         a->data = b->data;
  1279.         b->bits = tb;
  1280.         b->data = td;
  1281.       }
  1282.     }
  1283.     if(b == buf)
  1284.       ++buf;
  1285.     else
  1286.     {
  1287.       tb = buf->bits;
  1288.       td = buf->data;
  1289.       buf->bits = b->bits;
  1290.       buf->data = b->data;
  1291.       b->bits = tb;
  1292.       b->data = td;
  1293.       if(buf2-b-1 > b-buf)
  1294.       {
  1295.         SIT13_SortTree(s, buf, b);
  1296.         buf = b+1;
  1297.       }
  1298.       else
  1299.       {
  1300.         SIT13_SortTree(s, b+1, buf2);
  1301.         buf2 = b;
  1302.       }
  1303.     }
  1304.   }
  1305. }
  1306.  
  1307. static void SIT13_Func2(struct SIT13Data *s, struct SIT13Buffer *buf, UWORD bits, struct SIT13Buffer *buf2)
  1308. {
  1309.   LONG i, j, k, l, m, n;
  1310.  
  1311.   SIT13_SortTree(s, buf2, buf2 + bits);
  1312.  
  1313.   l = k = j = 0;
  1314.   for(i = 0; i < bits; ++i)
  1315.   {
  1316.     l += k;
  1317.     m = buf2[i].bits;
  1318.     if(m != j)
  1319.     {
  1320.       if((j = m) == -1)
  1321.         k = 0;
  1322.       else
  1323.         k = 1 << (32-j);
  1324.     }
  1325.     if(j > 0)
  1326.     {
  1327.       for(n = m = 0; n < 8*4; n += 4)
  1328.         m += SIT13Bits[(l>>n)&0xF]<<(7*4-n);
  1329.       SIT13_Func1(s, buf, m, j, buf2[i].data);
  1330.     }
  1331.   }
  1332. }
  1333.  
  1334. static void SIT13_CreateStaticTree(struct SIT13Data *s, struct SIT13Buffer *buf, UWORD bits, UBYTE *bitsbuf)
  1335. {
  1336.   ULONG i;
  1337.  
  1338.   for(i = 0; i < bits; ++i)
  1339.   {
  1340.     s->Buffer5[i].data = i;
  1341.     s->Buffer5[i].bits = bitsbuf[i];
  1342.   }
  1343.   SIT13_Func2(s, buf, bits, s->Buffer5);
  1344. }
  1345.  
  1346. static void SIT13InitInfo(struct SIT13Data *s, UBYTE id)
  1347. {
  1348.   LONG i;
  1349.   UBYTE k, l = 0, *a, *b;
  1350.  
  1351.   a = s->TextBuf;
  1352.   b = (UBYTE *) SIT13Static+SIT13StaticPos[id-1];
  1353.   id &= 1;
  1354.  
  1355.   for(i = 658; i; --i)
  1356.   {
  1357.     k = id ? *b >> 4 : *(b++) & 0xF; id ^=1;
  1358.  
  1359.     if(!k)
  1360.     {
  1361.       l -= id ? *b >> 4 : *(b++) & 0xF; id ^= 1;
  1362.     }
  1363.     else
  1364.     {
  1365.       if(k == 15)
  1366.       {
  1367.         l += id ? *b >> 4 : *(b++) & 0xF; id ^= 1;
  1368.       }
  1369.       else
  1370.         l += k-7;
  1371.     }
  1372.     *(a++) = l;
  1373.   }
  1374. }
  1375.  
  1376. static void SIT13_Extract(struct SIT13Data *s, struct xadInOut *io)
  1377. {
  1378.   ULONG wpos = 0, j, k, l, size;
  1379.   struct SIT13Buffer *buf = s->Buffer3;
  1380.  
  1381.   while(!io->xio_Error)
  1382.   {
  1383.     k = xadIOReadBitsLow(io, 12);
  1384.     if((j = buf[k].bits) <= 12)
  1385.     {
  1386.       l = buf[k].data;
  1387.       xadIODropBitsLow(io, j);
  1388.     }
  1389.     else
  1390.     {
  1391.       xadIODropBitsLow(io, 12);
  1392.  
  1393.       j = buf[k].data;
  1394.       while(s->Buffer4[j].freq == -1)
  1395.         j = xadIOGetBitsLow(io, 1) ? s->Buffer4[j].d2 : s->Buffer4[j].d1;
  1396.       l = s->Buffer4[j].freq;
  1397.     }
  1398.     if(l < 0x100)
  1399.     {
  1400.       s->Window[wpos++] = xadIOPutChar(io, l);
  1401.       wpos &= 0xFFFF;
  1402.       buf = s->Buffer3;
  1403.     }
  1404.     else
  1405.     {
  1406.       buf = s->Buffer3b;
  1407.       if(l < 0x13E)
  1408.         size = l - 0x100 + 3;
  1409.       else
  1410.       {
  1411.         if(l == 0x13E)
  1412.           size = xadIOGetBitsLow(io, 10);
  1413.         else
  1414.         {
  1415.           if(l == 0x140)
  1416.             return;
  1417.           size = xadIOGetBitsLow(io, 15);
  1418.         }
  1419.         size += 65;
  1420.       }
  1421.       j = xadIOReadBitsLow(io, 12);
  1422.       k = s->Buffer2[j].bits;
  1423.       if(k <= 12)
  1424.       {
  1425.         l = s->Buffer2[j].data;
  1426.         xadIODropBitsLow(io, k);
  1427.       }
  1428.       else
  1429.       {
  1430.         xadIODropBitsLow(io, 12);
  1431.         j = s->Buffer2[j].data;
  1432.         while(s->Buffer4[j].freq == -1)
  1433.           j = xadIOGetBitsLow(io, 1) ? s->Buffer4[j].d2 : s->Buffer4[j].d1;
  1434.         l = s->Buffer4[j].freq;
  1435.       }
  1436.       k = 0;
  1437.       if(l--)
  1438.         k = (1 << l) | xadIOGetBitsLow(io, l);
  1439.       l = wpos+0x10000-(k+1);
  1440.       while(size--)
  1441.       {
  1442.         l &= 0xFFFF;
  1443.         s->Window[wpos++] = xadIOPutChar(io, s->Window[l++]);
  1444.         wpos &= 0xFFFF;
  1445.       }
  1446.     } /* l >= 0x100 */
  1447.   }
  1448. }
  1449.  
  1450. static void SIT13_CreateTree(struct SIT13Data *s, struct xadInOut *io, struct SIT13Buffer *buf, UWORD num)
  1451. {
  1452.   struct SIT13Buffer *b;
  1453.   ULONG i;
  1454.   UWORD data;
  1455.   BYTE bi = 0;
  1456.  
  1457.   for(i = 0; i < num; ++i)
  1458.   {
  1459.     b = &s->Buffer1[xadIOReadBitsLow(io, 12)];
  1460.     data = b->data;
  1461.     xadIODropBitsLow(io, b->bits);
  1462.  
  1463.     switch(data-0x1F)
  1464.     {
  1465.     case 0: bi = -1; break;
  1466.     case 1: ++bi; break;
  1467.     case 2: --bi; break;
  1468.     case 3:
  1469.       if(xadIOGetBitsLow(io, 1))
  1470.         s->Buffer5[i++].bits = bi;
  1471.       break;
  1472.     case 4:
  1473.       data = xadIOGetBitsLow(io, 3)+2;
  1474.       while(data--)
  1475.         s->Buffer5[i++].bits = bi;
  1476.       break;
  1477.     case 5:
  1478.       data = xadIOGetBitsLow(io, 6)+10;
  1479.       while(data--)
  1480.         s->Buffer5[i++].bits = bi;
  1481.       break;
  1482.     default: bi = data+1; break;
  1483.     }
  1484.     s->Buffer5[i].bits = bi;
  1485.   }
  1486.   for(i = 0; i < num; ++i)
  1487.     s->Buffer5[i].data = i;
  1488.   SIT13_Func2(s, buf, num, s->Buffer5);
  1489. }
  1490.  
  1491. static LONG SIT_13(struct xadInOut *io)
  1492. {
  1493.   ULONG i, j;
  1494.   struct xadMasterBase *xadMasterBase = io->xio_xadMasterBase;
  1495.   struct SIT13Data *s;
  1496.  
  1497.   if((s = xadAllocVec(sizeof(struct SIT13Data), MEMF_CLEAR)))
  1498.   {
  1499.     s->MaxBits = 1;
  1500.     for(i = 0; i < 37; ++i)
  1501.       SIT13_Func1(s, s->Buffer1, SIT13Info[i], SIT13InfoBits[i], i);
  1502.     for(i = 1; i < 0x704; ++i)
  1503.     {
  1504.       /* s->Buffer4[i].d1 = s->Buffer4[i].d2 = 0; */
  1505.       s->Buffer4[i].freq = -1;
  1506.     }
  1507.  
  1508.     j = xadIOGetChar(io);
  1509.     i = j>>4;
  1510.     if(i > 5)
  1511.       io->xio_Error = XADERR_ILLEGALDATA;
  1512.     else if(i)
  1513.     {
  1514.       SIT13InitInfo(s, i--);
  1515.       SIT13_CreateStaticTree(s, s->Buffer3, 0x141, s->TextBuf);
  1516.       SIT13_CreateStaticTree(s, s->Buffer3b, 0x141, s->TextBuf+0x141);
  1517.       SIT13_CreateStaticTree(s, s->Buffer2, SIT13StaticBits[i], s->TextBuf+0x282);
  1518.     }
  1519.     else
  1520.     {
  1521.       SIT13_CreateTree(s, io, s->Buffer3, 0x141);
  1522.       if(j&8)
  1523.         xadCopyMem(s->Buffer3, s->Buffer3b, 0x1000*sizeof(struct SIT13Buffer));
  1524.       else
  1525.         SIT13_CreateTree(s, io, s->Buffer3b, 0x141);
  1526.       j = (j&7)+10;
  1527.       SIT13_CreateTree(s, io, s->Buffer2, j);
  1528.     }
  1529.     if(!io->xio_Error)
  1530.       SIT13_Extract(s, io);
  1531.     xadFreeObjectA(s, 0);
  1532.   }
  1533.   return io->xio_Error;
  1534. }
  1535.  
  1536. /*****************************************************************************/
  1537.  
  1538. struct SIT14Data {
  1539.   struct xadInOut *io;
  1540.   UBYTE code[308];
  1541.   UBYTE codecopy[308];
  1542.   UWORD freq[308];
  1543.   ULONG buff[308];
  1544.  
  1545.   UBYTE var1[52];
  1546.   UWORD var2[52];
  1547.   UWORD var3[75*2];
  1548.  
  1549.   UBYTE var4[76];
  1550.   ULONG var5[75];
  1551.   UBYTE var6[1024];
  1552.   UWORD var7[308*2];
  1553.   UBYTE var8[0x4000];
  1554.  
  1555.   UBYTE Window[0x40000];
  1556. };
  1557.  
  1558. static void SIT14_Update(UWORD first, UWORD last, UBYTE *code, UWORD *freq)
  1559. {
  1560.   UWORD i, j;
  1561.  
  1562.   while(last-first > 1)
  1563.   {
  1564.     i = first;
  1565.     j = last;
  1566.  
  1567.     do
  1568.     {
  1569.       while(++i < last && code[first] > code[i])
  1570.         ;
  1571.       while(--j > first && code[first] < code[j])
  1572.         ;
  1573.       if(j > i)
  1574.       {
  1575.         UWORD t;
  1576.         t = code[i]; code[i] = code[j]; code[j] = t;
  1577.         t = freq[i]; freq[i] = freq[j]; freq[j] = t;
  1578.       }
  1579.     } while(j > i);
  1580.  
  1581.     if(first != j)
  1582.     {
  1583.       {
  1584.         UWORD t;
  1585.         t = code[first]; code[first] = code[j]; code[j] = t;
  1586.         t = freq[first]; freq[first] = freq[j]; freq[j] = t;
  1587.       }
  1588.  
  1589.       i = j+1;
  1590.       if(last-i <= j-first)
  1591.       {
  1592.         SIT14_Update(i, last, code, freq);
  1593.         last = j;
  1594.       }
  1595.       else
  1596.       {
  1597.         SIT14_Update(first, j, code, freq);
  1598.         first = i;
  1599.       }
  1600.     }
  1601.     else
  1602.       ++first;
  1603.   }
  1604. }
  1605.  
  1606. static void SIT14_ReadTree(struct SIT14Data *dat, UWORD codesize, UWORD *result)
  1607. {
  1608.   ULONG size, i, j, k, l, m, n, o;
  1609.  
  1610.   k = xadIOGetBitsLow(dat->io, 1);
  1611.   j = xadIOGetBitsLow(dat->io, 2)+2;
  1612.   o = xadIOGetBitsLow(dat->io, 3)+1;
  1613.   size = 1<<j;
  1614.   m = size-1;
  1615.   k = k ? m-1 : -1;
  1616.   if(xadIOGetBitsLow(dat->io, 2)&1) /* skip 1 bit! */
  1617.   {
  1618.     /* requirements for this call: dat->buff[32], dat->code[32], dat->freq[32*2] */
  1619.     SIT14_ReadTree(dat, size, dat->freq);
  1620.     for(i = 0; i < codesize; )
  1621.     {
  1622.       l = 0;
  1623.       do
  1624.       {
  1625.         l = dat->freq[l + xadIOGetBitsLow(dat->io, 1)];
  1626.         n = size<<1;
  1627.       } while(n > l);
  1628.       l -= n;
  1629.       if(k != l)
  1630.       {
  1631.         if(l == m)
  1632.         {
  1633.           l = 0;
  1634.           do
  1635.           {
  1636.             l = dat->freq[l + xadIOGetBitsLow(dat->io, 1)];
  1637.             n = size<<1;
  1638.           } while(n > l);
  1639.           l += 3-n;
  1640.           while(l--)
  1641.           {
  1642.             dat->code[i] = dat->code[i-1];
  1643.             ++i;
  1644.           }
  1645.         }
  1646.         else
  1647.           dat->code[i++] = l+o;
  1648.       }
  1649.       else
  1650.         dat->code[i++] = 0;
  1651.     }
  1652.   }
  1653.   else
  1654.   {
  1655.     for(i = 0; i < codesize; )
  1656.     {
  1657.       l = xadIOGetBitsLow(dat->io, j);
  1658.       if(k != l)
  1659.       {
  1660.         if(l == m)
  1661.         {
  1662.           l = xadIOGetBitsLow(dat->io, j)+3;
  1663.           while(l--)
  1664.           {
  1665.             dat->code[i] = dat->code[i-1];
  1666.             ++i;
  1667.           }
  1668.         }
  1669.         else
  1670.           dat->code[i++] = l+o;
  1671.       }
  1672.       else
  1673.         dat->code[i++] = 0;
  1674.     }
  1675.   }
  1676.  
  1677.   for(i = 0; i < codesize; ++i)
  1678.   {
  1679.     dat->codecopy[i] = dat->code[i];
  1680.     dat->freq[i] = i;
  1681.   }
  1682.   SIT14_Update(0, codesize, dat->codecopy, dat->freq);
  1683.  
  1684.   for(i = 0; i < codesize && !dat->codecopy[i]; ++i)
  1685.     ; /* find first nonempty */
  1686.   for(j = 0; i < codesize; ++i, ++j)
  1687.   {
  1688.     if(i)
  1689.       j <<= (dat->codecopy[i] - dat->codecopy[i-1]);
  1690.  
  1691.     k = dat->codecopy[i]; m = 0;
  1692.     for(l = j; k--; l >>= 1)
  1693.       m = (m << 1) | (l&1);
  1694.  
  1695.     dat->buff[dat->freq[i]] = m;
  1696.   }
  1697.  
  1698.   for(i = 0; i < codesize*2; ++i)
  1699.     result[i] = 0;
  1700.  
  1701.   j = 2;
  1702.   for(i = 0; i < codesize; ++i)
  1703.   {
  1704.     l = 0;
  1705.     m = dat->buff[i];
  1706.  
  1707.     for(k = 0; k < dat->code[i]; ++k)
  1708.     {
  1709.       l += (m&1);
  1710.       if(dat->code[i]-1 <= k)
  1711.         result[l] = codesize*2+i;
  1712.       else
  1713.       {
  1714.         if(!result[l])
  1715.         {
  1716.           result[l] = j; j += 2;
  1717.         }
  1718.         l = result[l];
  1719.       }
  1720.       m >>= 1;
  1721.     }
  1722.   }
  1723.   xadIOByteBoundary(dat->io);
  1724. }
  1725.  
  1726. static LONG SIT_14(struct xadInOut *io)
  1727. {
  1728.   ULONG i, j, k, l, m, n;
  1729.   struct xadMasterBase *xadMasterBase = io->xio_xadMasterBase;
  1730.   struct SIT14Data *dat;
  1731.  
  1732.   if((dat = (struct SIT14Data *) xadAllocVec(sizeof(struct SIT14Data), MEMF_ANY|MEMF_CLEAR)))
  1733.   {
  1734.     dat->io = io;
  1735.  
  1736.     /* initialization */
  1737.     for(i = k = 0; i < 52; ++i)
  1738.     {
  1739.       dat->var2[i] = k;
  1740.       k += (1<<(dat->var1[i] = ((i >= 4) ? ((i-4)>>2) : 0)));
  1741.     }
  1742.     for(i = 0; i < 4; ++i)
  1743.       dat->var8[i] = i;
  1744.     for(m = 1, l = 4; i < 0x4000; m <<= 1) /* i is 4 */
  1745.     {
  1746.       for(n = l+4; l < n; ++l)
  1747.       {
  1748.         for(j = 0; j < m; ++j)
  1749.           dat->var8[i++] = l;
  1750.       }
  1751.     }
  1752.     for(i = 0, k = 1; i < 75; ++i)
  1753.     {
  1754.       dat->var5[i] = k;
  1755.       k += (1<<(dat->var4[i] = (i >= 3 ? ((i-3)>>2) : 0)));
  1756.     }
  1757.     for(i = 0; i < 4; ++i)
  1758.       dat->var6[i] = i-1;
  1759.     for(m = 1, l = 3; i < 0x400; m <<= 1) /* i is 4 */
  1760.     {
  1761.       for(n = l+4; l < n; ++l)
  1762.       {
  1763.         for(j = 0; j < m; ++j)
  1764.           dat->var6[i++] = l;
  1765.       }
  1766.     }
  1767.  
  1768.     m = xadIOGetBitsLow(io, 16); /* number of blocks */
  1769.     j = 0; /* window position */
  1770.     while(m-- && !(io->xio_Flags & (XADIOF_ERROR|XADIOF_LASTOUTBYTE)))
  1771.     {
  1772.       /* these functions do not support access > 24 bit */
  1773.       xadIOGetBitsLow(io, 16); /* skip crunched block size */
  1774.       xadIOGetBitsLow(io, 16);
  1775.       n = xadIOGetBitsLow(io, 16); /* number of uncrunched bytes */
  1776.       n |= xadIOGetBitsLow(io, 16)<<16;
  1777.       SIT14_ReadTree(dat, 308, dat->var7);
  1778.       SIT14_ReadTree(dat, 75, dat->var3);
  1779.  
  1780.       while(n && !(io->xio_Flags & (XADIOF_ERROR|XADIOF_LASTOUTBYTE)))
  1781.       {
  1782.         for(i = 0; i < 616;)
  1783.           i = dat->var7[i + xadIOGetBitsLow(io, 1)];
  1784.         i -= 616;
  1785.         if(i < 0x100)
  1786.         {
  1787.           dat->Window[j++] = xadIOPutChar(io, i);
  1788.           j &= 0x3FFFF;
  1789.           --n;
  1790.         }
  1791.         else
  1792.         {
  1793.           i -= 0x100;
  1794.           k = dat->var2[i]+4;
  1795.           i = dat->var1[i];
  1796.           if(i)
  1797.             k += xadIOGetBitsLow(io, i);
  1798.           for(i = 0; i < 150;)
  1799.             i = dat->var3[i + xadIOGetBitsLow(io, 1)];
  1800.           i -= 150;
  1801.           l = dat->var5[i];
  1802.           i = dat->var4[i];
  1803.           if(i)
  1804.             l += xadIOGetBitsLow(io, i);
  1805.           n -= k;
  1806.           l = j+0x40000-l;
  1807.           while(k--)
  1808.           {
  1809.             l &= 0x3FFFF;
  1810.             dat->Window[j++] = xadIOPutChar(io, dat->Window[l++]);
  1811.             j &= 0x3FFFF;
  1812.           }
  1813.         }
  1814.       }
  1815.       xadIOByteBoundary(io);
  1816.     }
  1817.     xadFreeObjectA(dat, 0);
  1818.   }
  1819.   return io->xio_Error;
  1820. }
  1821.  
  1822. /*****************************************************************************/
  1823.  
  1824. static UWORD SIT_rndtable[] = {
  1825.  0xee,  0x56,  0xf8,  0xc3,  0x9d,  0x9f,  0xae,  0x2c,
  1826.  0xad,  0xcd,  0x24,  0x9d,  0xa6, 0x101,  0x18,  0xb9,
  1827.  0xa1,  0x82,  0x75,  0xe9,  0x9f,  0x55,  0x66,  0x6a,
  1828.  0x86,  0x71,  0xdc,  0x84,  0x56,  0x96,  0x56,  0xa1,
  1829.  0x84,  0x78,  0xb7,  0x32,  0x6a,   0x3,  0xe3,   0x2,
  1830.  0x11, 0x101,   0x8,  0x44,  0x83, 0x100,  0x43,  0xe3,
  1831.  0x1c,  0xf0,  0x86,  0x6a,  0x6b,   0xf,   0x3,  0x2d,
  1832.  0x86,  0x17,  0x7b,  0x10,  0xf6,  0x80,  0x78,  0x7a,
  1833.  0xa1,  0xe1,  0xef,  0x8c,  0xf6,  0x87,  0x4b,  0xa7,
  1834.  0xe2,  0x77,  0xfa,  0xb8,  0x81,  0xee,  0x77,  0xc0,
  1835.  0x9d,  0x29,  0x20,  0x27,  0x71,  0x12,  0xe0,  0x6b,
  1836.  0xd1,  0x7c,   0xa,  0x89,  0x7d,  0x87,  0xc4, 0x101,
  1837.  0xc1,  0x31,  0xaf,  0x38,   0x3,  0x68,  0x1b,  0x76,
  1838.  0x79,  0x3f,  0xdb,  0xc7,  0x1b,  0x36,  0x7b,  0xe2,
  1839.  0x63,  0x81,  0xee,   0xc,  0x63,  0x8b,  0x78,  0x38,
  1840.  0x97,  0x9b,  0xd7,  0x8f,  0xdd,  0xf2,  0xa3,  0x77,
  1841.  0x8c,  0xc3,  0x39,  0x20,  0xb3,  0x12,  0x11,   0xe,
  1842.  0x17,  0x42,  0x80,  0x2c,  0xc4,  0x92,  0x59,  0xc8,
  1843.  0xdb,  0x40,  0x76,  0x64,  0xb4,  0x55,  0x1a,  0x9e,
  1844.  0xfe,  0x5f,   0x6,  0x3c,  0x41,  0xef,  0xd4,  0xaa,
  1845.  0x98,  0x29,  0xcd,  0x1f,   0x2,  0xa8,  0x87,  0xd2,
  1846.  0xa0,  0x93,  0x98,  0xef,   0xc,  0x43,  0xed,  0x9d,
  1847.  0xc2,  0xeb,  0x81,  0xe9,  0x64,  0x23,  0x68,  0x1e,
  1848.  0x25,  0x57,  0xde,  0x9a,  0xcf,  0x7f,  0xe5,  0xba,
  1849.  0x41,  0xea,  0xea,  0x36,  0x1a,  0x28,  0x79,  0x20,
  1850.  0x5e,  0x18,  0x4e,  0x7c,  0x8e,  0x58,  0x7a,  0xef,
  1851.  0x91,   0x2,  0x93,  0xbb,  0x56,  0xa1,  0x49,  0x1b,
  1852.  0x79,  0x92,  0xf3,  0x58,  0x4f,  0x52,  0x9c,   0x2,
  1853.  0x77,  0xaf,  0x2a,  0x8f,  0x49,  0xd0,  0x99,  0x4d,
  1854.  0x98, 0x101,  0x60,  0x93, 0x100,  0x75,  0x31,  0xce,
  1855.  0x49,  0x20,  0x56,  0x57,  0xe2,  0xf5,  0x26,  0x2b,
  1856.  0x8a,  0xbf,  0xde,  0xd0,  0x83,  0x34,  0xf4,  0x17
  1857. };
  1858.  
  1859. struct SIT_modelsym
  1860. {
  1861.   UWORD sym;
  1862.   ULONG cumfreq;
  1863. };
  1864.  
  1865. struct SIT_model
  1866. {
  1867.   LONG                increment;
  1868.   LONG                maxfreq;
  1869.   LONG                entries;
  1870.   ULONG               tabloc[256];
  1871.   struct SIT_modelsym *syms;
  1872. };
  1873.  
  1874. struct SIT_ArsenicData
  1875. {
  1876.   struct xadInOut *io;
  1877.  
  1878.   UWORD  csumaccum;
  1879.   UBYTE *window;
  1880.   UBYTE *windowpos;
  1881.   UBYTE *windowe;
  1882.   LONG   windowsize;
  1883.   LONG   tsize;
  1884.   ULONG  One;
  1885.   ULONG  Half;
  1886.   ULONG  Range;
  1887.   ULONG  Code;
  1888.   LONG   lastarithbits; /* init 0 */
  1889.  
  1890.   /* SIT_dounmntf function private */
  1891.   LONG   inited;        /* init 0 */
  1892.   UBYTE  moveme[256];
  1893.  
  1894.   /* the private SIT_Arsenic function stuff */
  1895.   struct SIT_model initial_model;
  1896.   struct SIT_model selmodel;
  1897.   struct SIT_model mtfmodel[7];
  1898.   struct SIT_modelsym initial_syms[2+1];
  1899.   struct SIT_modelsym sel_syms[11+1];
  1900.   struct SIT_modelsym mtf0_syms[2+1];
  1901.   struct SIT_modelsym mtf1_syms[4+1];
  1902.   struct SIT_modelsym mtf2_syms[8+1];
  1903.   struct SIT_modelsym mtf3_syms[0x10+1];
  1904.   struct SIT_modelsym mtf4_syms[0x20+1];
  1905.   struct SIT_modelsym mtf5_syms[0x40+1];
  1906.   struct SIT_modelsym mtf6_syms[0x80+1];
  1907.  
  1908.   /* private for SIT_unblocksort */
  1909.   ULONG counts[256];
  1910.   ULONG cumcounts[256];
  1911. };
  1912.  
  1913. static void SIT_update_model(struct SIT_model *mymod, LONG symindex)
  1914. {
  1915.   LONG i;
  1916.  
  1917.   for (i = 0; i < symindex; i++)
  1918.     mymod->syms[i].cumfreq += mymod->increment;
  1919.   if(mymod->syms[0].cumfreq > mymod->maxfreq)
  1920.   {
  1921.     for(i = 0; i < mymod->entries ; i++)
  1922.     {
  1923.       /* no -1, want to include the 0 entry */
  1924.       /* this converts cumfreqs LONGo frequencies, then shifts right */
  1925.       mymod->syms[i].cumfreq -= mymod->syms[i+1].cumfreq;
  1926.       mymod->syms[i].cumfreq++; /* avoid losing things entirely */
  1927.       mymod->syms[i].cumfreq >>= 1;
  1928.     }
  1929.     /* then convert frequencies back to cumfreq */
  1930.     for(i = mymod->entries - 1; i >= 0; i--)
  1931.       mymod->syms[i].cumfreq += mymod->syms[i+1].cumfreq;
  1932.   }
  1933. }
  1934.  
  1935. static void SIT_getcode(struct SIT_ArsenicData *sa,
  1936. ULONG symhigh, ULONG symlow, ULONG symtot) /* aka remove symbol */
  1937. {
  1938.   ULONG lowincr;
  1939.   ULONG renorm_factor;
  1940.  
  1941.   renorm_factor = sa->Range/symtot;
  1942.   lowincr = renorm_factor * symlow;
  1943.   sa->Code -= lowincr;
  1944.   if(symhigh == symtot)
  1945.     sa->Range -= lowincr;
  1946.   else
  1947.     sa->Range = (symhigh - symlow) * renorm_factor;
  1948.   
  1949.   sa->lastarithbits = 0;
  1950.   while(sa->Range <= sa->Half)
  1951.   {
  1952.     sa->Range <<= 1;
  1953.     sa->Code = (sa->Code << 1) | xadIOGetBitsHigh(sa->io, 1);
  1954.     sa->lastarithbits++;
  1955.   }
  1956. }
  1957.  
  1958. static LONG SIT_getsym(struct SIT_ArsenicData *sa, struct SIT_model *model)
  1959. {
  1960.   LONG freq;
  1961.   LONG i;
  1962.   LONG sym;
  1963.  
  1964.   /* getfreq */
  1965.   freq = sa->Code/(sa->Range/model->syms[0].cumfreq);
  1966.   for(i = 1; i < model->entries; i++)
  1967.   {
  1968.     if(model->syms[i].cumfreq <= freq)
  1969.       break;
  1970.   }
  1971.   sym = model->syms[i-1].sym;
  1972.   SIT_getcode(sa, model->syms[i-1].cumfreq, model->syms[i].cumfreq, model->syms[0].cumfreq);
  1973.   SIT_update_model(model, i);
  1974.   return sym;
  1975. }
  1976.  
  1977. static void SIT_reinit_model(struct SIT_model *mymod)
  1978. {
  1979.   LONG cumfreq = mymod->entries * mymod->increment;
  1980.   LONG i;
  1981.  
  1982.   for(i = 0; i <= mymod->entries; i++)
  1983.   {
  1984.     /* <= sets last frequency to 0; there isn't really a symbol for that
  1985.        last one  */
  1986.     mymod->syms[i].cumfreq = cumfreq;
  1987.     cumfreq -= mymod->increment;
  1988.   }
  1989. }
  1990.  
  1991. static void SIT_init_model(struct SIT_model *newmod, struct SIT_modelsym *sym,
  1992. LONG entries, LONG start, LONG increment, LONG maxfreq)
  1993. {
  1994.   LONG i;
  1995.  
  1996.   newmod->syms = sym;
  1997.   newmod->increment = increment;
  1998.   newmod->maxfreq = maxfreq;
  1999.   newmod->entries = entries;
  2000.   /* memset(newmod->tabloc, 0, sizeof(newmod->tabloc)); */
  2001.   for(i = 0; i < entries; i++)
  2002.   {
  2003.     newmod->tabloc[(entries - i - 1) + start] = i;
  2004.     newmod->syms[i].sym = (entries - i - 1) + start;
  2005.   }
  2006.   SIT_reinit_model(newmod);
  2007. }
  2008.  
  2009. static ULONG SIT_arith_getbits(struct SIT_ArsenicData *sa, struct SIT_model *model, LONG nbits)
  2010. {
  2011.   /* the model is assumed to be a binary one */
  2012.   ULONG addme = 1;
  2013.   ULONG accum = 0;
  2014.   while(nbits--)
  2015.   {
  2016.     if(SIT_getsym(sa, model)) 
  2017.       accum += addme;
  2018.     addme += addme;
  2019.   }
  2020.   return accum;
  2021. }
  2022.  
  2023. static LONG SIT_dounmtf(struct SIT_ArsenicData *sa, LONG sym)
  2024. {
  2025.   LONG i;
  2026.   LONG result;
  2027.  
  2028.   if(sym == -1 || !sa->inited)
  2029.   {
  2030.     for(i = 0; i < 256; i++)
  2031.       sa->moveme[i] = i;
  2032.     sa->inited = 1;
  2033.   }
  2034.   if(sym == -1)
  2035.     return 0;
  2036.   result = sa->moveme[sym];
  2037.   for(i = sym; i > 0 ; i-- )
  2038.     sa->moveme[i] = sa->moveme[i-1];
  2039.   
  2040.   sa->moveme[0] = result;
  2041.   return result;
  2042. }
  2043.  
  2044. static LONG SIT_unblocksort(struct SIT_ArsenicData *sa, UBYTE *block,
  2045. ULONG blocklen, ULONG last_index, UBYTE *outblock)
  2046. {
  2047.   ULONG i, j;
  2048.   ULONG *xform;
  2049.   UBYTE *blockptr;
  2050.   ULONG cum;
  2051.   struct xadMasterBase *xadMasterBase = sa->io->xio_xadMasterBase;
  2052.  
  2053.   memset(sa->counts, 0, sizeof(sa->counts));
  2054.   if((xform = xadAllocVec(sizeof(ULONG)*blocklen, MEMF_ANY)))
  2055.   {
  2056.     blockptr = block;
  2057.     for(i = 0; i < blocklen; i++)
  2058.       sa->counts[*blockptr++]++;
  2059.   
  2060.     cum = 0;
  2061.     for(i = 0; i < 256; i++)
  2062.     {
  2063.       sa->cumcounts[i] = cum;
  2064.       cum += sa->counts[i];
  2065.       sa->counts[i] = 0;
  2066.     }
  2067.  
  2068.     blockptr = block;
  2069.     for(i = 0; i < blocklen; i++)
  2070.     {
  2071.       xform[sa->cumcounts[*blockptr] + sa->counts[*blockptr]] = i;
  2072.       sa->counts[*blockptr++]++;
  2073.     }
  2074.  
  2075.     blockptr = outblock;
  2076.     for(i = 0, j = xform[last_index]; i < blocklen; i++, j = xform[j])
  2077.     {
  2078.       *blockptr++ = block[j];
  2079. //      block[j] = 0xa5; /* for debugging */
  2080.     }
  2081.     xadFreeObjectA(xform, 0);
  2082.   }
  2083.   else
  2084.     return XADERR_NOMEMORY;
  2085.   return 0;
  2086. }
  2087.  
  2088. static void SIT_write_and_unrle_and_unrnd(struct xadInOut *io, UBYTE *block, ULONG blocklen, WORD rnd)
  2089. {
  2090.   LONG count = 0;
  2091.   LONG last = 0;
  2092.   UBYTE *blockptr = block;
  2093.   ULONG i;
  2094.   ULONG j;
  2095.   LONG ch;
  2096.   LONG rndindex;
  2097.   LONG rndcount;
  2098.  
  2099.   rndindex = 0;
  2100.   rndcount = SIT_rndtable[rndindex];
  2101.   for(i = 0; i < blocklen; i++)
  2102.   {
  2103.     ch = *blockptr++;
  2104.     if(rnd && (rndcount == 0))
  2105.     {
  2106.       ch ^= 1;
  2107.       rndindex++;
  2108.       if (rndindex == sizeof(SIT_rndtable)/sizeof(SIT_rndtable[0]))
  2109.     rndindex = 0;
  2110.       rndcount = SIT_rndtable[rndindex];
  2111.     }
  2112.     rndcount--;
  2113.  
  2114.     if(count == 4)
  2115.     {
  2116.       for(j = 0; j < ch; j++)
  2117.     xadIOPutChar(io, last);
  2118.       count = 0;
  2119.     }
  2120.     else
  2121.     {
  2122.       xadIOPutChar(io, ch);
  2123.       if(ch != last)
  2124.       {
  2125.     count = 0;
  2126.     last = ch;
  2127.       }
  2128.       count++;
  2129.     }
  2130.   }
  2131. }
  2132.  
  2133. static LONG SIT_Arsenic(struct xadInOut *io)
  2134. {
  2135.   LONG err = 0;
  2136.   struct SIT_ArsenicData *sa;
  2137.   struct xadMasterBase *xadMasterBase = io->xio_xadMasterBase;
  2138.  
  2139.   io->xio_Flags &= ~(XADIOF_NOCRC32);
  2140.   io->xio_Flags |= XADIOF_NOCRC16;
  2141.   io->xio_CRC32 = ~0;
  2142.  
  2143.   if((sa = (struct SIT_ArsenicData *) xadAllocVec(sizeof(struct SIT_ArsenicData), MEMF_ANY|MEMF_CLEAR)))
  2144.   {
  2145.     LONG i, sym, sel;
  2146.     WORD blockbits;
  2147.     ULONG w, blocksize;
  2148.     LONG stopme, nchars; /* 32 bits */
  2149.     LONG repeatstate, repeatcount;
  2150.     LONG primary_index; /* 32 bits */
  2151.     LONG eob, rnd;
  2152.     UBYTE *block, *blockptr, *unsortedblock;
  2153.  
  2154.     sa->io = io;
  2155.     sa->Range = sa->One = 1<<25;
  2156.     sa->Half = 1<<24;
  2157.     sa->Code = xadIOGetBitsHigh(io, 26);
  2158.  
  2159.     SIT_init_model(&sa->initial_model, sa->initial_syms, 2, 0, 1, 256);
  2160.     SIT_init_model(&sa->selmodel, sa->sel_syms, 11, 0, 8, 1024);
  2161.     /* selector model: 11 selections, starting at 0, 8 increment, 1024 maxfreq */
  2162.  
  2163.     SIT_init_model(&sa->mtfmodel[0], sa->mtf0_syms, 2, 2, 8, 1024);
  2164.     /* model 3: 2 symbols, starting at 2, 8 increment, 1024 maxfreq */
  2165.     SIT_init_model(&sa->mtfmodel[1], sa->mtf1_syms, 4, 4, 4, 1024);
  2166.     /* model 4: 4 symbols, starting at 4, 4 increment, 1024 maxfreq */
  2167.     SIT_init_model(&sa->mtfmodel[2], sa->mtf2_syms, 8, 8, 4, 1024);
  2168.     /* model 5: 8 symbols, starting at 8, 4 increment, 1024 maxfreq */
  2169.     SIT_init_model(&sa->mtfmodel[3], sa->mtf3_syms, 0x10, 0x10, 4, 1024);
  2170.     /* model 6: $10 symbols, starting at $10, 4 increment, 1024 maxfreq */
  2171.     SIT_init_model(&sa->mtfmodel[4], sa->mtf4_syms, 0x20, 0x20, 2, 1024);
  2172.     /* model 7: $20 symbols, starting at $20, 2 increment, 1024 maxfreq */
  2173.     SIT_init_model(&sa->mtfmodel[5], sa->mtf5_syms, 0x40, 0x40, 2, 1024);
  2174.     /* model 8: $40 symbols, starting at $40, 2 increment, 1024 maxfreq */
  2175.     SIT_init_model(&sa->mtfmodel[6], sa->mtf6_syms, 0x80, 0x80, 1, 1024);
  2176.     /* model 9: $80 symbols, starting at $80, 1 increment, 1024 maxfreq */
  2177.     if(SIT_arith_getbits(sa, &sa->initial_model, 8) != 0x41 ||
  2178.     SIT_arith_getbits(sa, &sa->initial_model, 8) != 0x73)
  2179.       err = XADERR_ILLEGALDATA;
  2180.     w = SIT_arith_getbits(sa, &sa->initial_model, 4);
  2181.     blockbits = w + 9;
  2182.     blocksize = 1<<blockbits;
  2183.     if(!err)
  2184.     {
  2185.       if((block = xadAllocVec(blocksize, MEMF_ANY)))
  2186.       {
  2187.         if((unsortedblock = xadAllocVec(blocksize, MEMF_ANY)))
  2188.         {
  2189.           eob = SIT_getsym(sa, &sa->initial_model);
  2190.           while(!eob && !err)
  2191.           {
  2192.             rnd = SIT_getsym(sa, &sa->initial_model);
  2193.             primary_index = SIT_arith_getbits(sa, &sa->initial_model, blockbits);
  2194.             nchars = stopme = repeatstate = repeatcount = 0;
  2195.             blockptr = block;
  2196.             while(!stopme)
  2197.             {
  2198.               sel = SIT_getsym(sa, &sa->selmodel);
  2199.               switch(sel)
  2200.               {
  2201.               case 0:
  2202.             sym = -1;
  2203.                 if(!repeatstate)
  2204.                   repeatstate = repeatcount = 1;
  2205.                 else
  2206.                 {
  2207.                   repeatstate += repeatstate;
  2208.                   repeatcount += repeatstate;
  2209.                 }
  2210.                 break;
  2211.               case 1:
  2212.                 if(!repeatstate)
  2213.                 {
  2214.                   repeatstate = 1;
  2215.                   repeatcount = 2;
  2216.                 }
  2217.                 else
  2218.                 {
  2219.                   repeatstate += repeatstate;
  2220.                   repeatcount += repeatstate;
  2221.                   repeatcount += repeatstate;
  2222.                 }
  2223.                 sym = -1;
  2224.                 break;
  2225.               case 2:
  2226.                 sym = 1;
  2227.                 break;
  2228.               case 10:
  2229.                 stopme = 1;
  2230.                 sym = 0;
  2231.                 break;
  2232.               default: 
  2233.                 if((sel > 9) || (sel < 3))
  2234.                 { /* this basically can't happen */
  2235.                   err = XADERR_ILLEGALDATA;
  2236.                   stopme = 1;
  2237.                   sym = 0;
  2238.                 }
  2239.                 else
  2240.                   sym = SIT_getsym(sa, &sa->mtfmodel[sel-3]);
  2241.                 break;
  2242.               }
  2243.               if(repeatstate && (sym >= 0))
  2244.               {
  2245.                 nchars += repeatcount;
  2246.                 repeatstate = 0;
  2247.                 memset(blockptr, SIT_dounmtf(sa, 0), repeatcount);
  2248.                 blockptr += repeatcount;
  2249.                 repeatcount = 0;
  2250.               }
  2251.               if(!stopme && !repeatstate)
  2252.               {
  2253.                 sym = SIT_dounmtf(sa, sym);
  2254.                 *blockptr++ = sym;
  2255.                 nchars++;
  2256.               }
  2257.               if(nchars > blocksize)
  2258.               {
  2259.                 err = XADERR_ILLEGALDATA;
  2260.                 stopme = 1;
  2261.               }
  2262.             }
  2263.             if(err)
  2264.               break;
  2265.             if((err = SIT_unblocksort(sa, block, nchars, primary_index, unsortedblock)))
  2266.               break;
  2267.             SIT_write_and_unrle_and_unrnd(io, unsortedblock, nchars, rnd);
  2268.             eob = SIT_getsym(sa, &sa->initial_model);
  2269.             SIT_reinit_model(&sa->selmodel);
  2270.             for(i = 0; i < 7; i ++)
  2271.               SIT_reinit_model(&sa->mtfmodel[i]);
  2272.             SIT_dounmtf(sa, -1);
  2273.           }
  2274.           if(!err)
  2275.           {
  2276.             err = xadIOWriteBuf(io);
  2277.             if(!err && SIT_arith_getbits(sa, &sa->initial_model, 32) != ~io->xio_CRC32)
  2278.               err = XADERR_CHECKSUM;
  2279.           }
  2280.           xadFreeObjectA(unsortedblock, 0);
  2281.         }
  2282.         else
  2283.           err = XADERR_NOMEMORY;
  2284.         xadFreeObjectA(block, 0);
  2285.       }
  2286.       else
  2287.         err = XADERR_NOMEMORY;
  2288.     } /* if(!err) */
  2289.     xadFreeObjectA(sa, 0);
  2290.   }
  2291.   else
  2292.     err = XADERR_NOMEMORY;
  2293.  
  2294.   return err;
  2295. }
  2296.  
  2297. /*****************************************************************************/
  2298.  
  2299. ASM(LONG) SIT_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  2300. REG(a6, struct xadMasterBase *xadMasterBase))
  2301. {
  2302.   struct xadFileInfo *fi;
  2303.   struct xadInOut *io;
  2304.   LONG err;
  2305.  
  2306.   fi = ai->xai_CurFile;
  2307.  
  2308.   if((io = xadIOAlloc(XADIOF_ALLOCINBUFFER|XADIOF_ALLOCOUTBUFFER|XADIOF_NOCRC32, ai, xadMasterBase)))
  2309.   {
  2310.     io->xio_InSize = fi->xfi_CrunchSize;
  2311.     io->xio_OutSize = fi->xfi_Size;
  2312.  
  2313.     switch(SITPI(fi)->Method)
  2314.     {
  2315.     case SITnocomp:
  2316.       while(!(io->xio_Flags & (XADIOF_LASTOUTBYTE|XADIOF_ERROR)))
  2317.         xadIOPutChar(io, xadIOGetChar(io));
  2318.       err = io->xio_Error;
  2319.       break;
  2320.     case SITrle: err = SIT_rle(io); break;
  2321.     case SITlzc: err = UCompDecomp(io, 14|UCOMPBLOCK_MASK); break;
  2322.     case SIThuffman: err = SIT_huffman(io); break;
  2323.     case SITlzah: err = SIT_lzah(io); break;
  2324.     case SITmw: err = SIT_mw(io); break;
  2325.     case 13: io->xio_Flags |= XADIOF_NOINENDERR; err = SIT_13(io); break;
  2326.     case 14: err = SIT_14(io); break;
  2327.     case 15: err = SIT_Arsenic(io); break;
  2328.     default:
  2329. #ifdef DEBUG
  2330.       {
  2331.         UBYTE data[4];
  2332.         data[0] = 'S'; data[1] = 'I'; data[2] = 'T'; data[3] = SITPI(fi)->Method;
  2333.         xadHookAccess(XADAC_WRITE, 4, data, ai);
  2334.         xadHookAccess(XADAC_WRITE, 4, &fi->xfi_Size, ai);
  2335.         xadHookAccess(XADAC_WRITE, 4, &fi->xfi_CrunchSize, ai);
  2336.         xadHookAccess(XADAC_WRITE, 2, &(SITPI(fi)->CRC), ai);
  2337.         xadHookAccess(XADAC_COPY, fi->xfi_CrunchSize, 0, ai);
  2338.       }
  2339. #endif
  2340.       err = XADERR_DATAFORMAT;
  2341.     }
  2342.     if(SITPI(fi)->Method != 15)
  2343.     {
  2344.       if(!err)
  2345.         err = xadIOWriteBuf(io);
  2346.       if(!err && io->xio_CRC16 != SITPI(fi)->CRC)
  2347.         err = XADERR_CHECKSUM;
  2348.     }
  2349.     xadFreeObjectA(io, 0);
  2350.   }
  2351.   else
  2352.     err = XADERR_NOMEMORY;
  2353.  
  2354.   return err;
  2355. }
  2356.  
  2357. /*****************************************************************************/
  2358.  
  2359. ASM(BOOL) SIT5_RecogData(REG(d0, ULONG size), REG(a0, UBYTE *data),
  2360. REG(a6, struct xadMasterBase *xadMasterBase))
  2361. { CPUCHECK
  2362.   {
  2363.     STRPTR a = "StuffIt (c)1997-\xFF\xFF\xFF\xFF Aladdin Systems, Inc., http://www.aladdinsys.com/StuffIt/\x0d\x0a";
  2364.  
  2365.     while(*a && (*a == *data || *a == 0xFF))
  2366.     {
  2367.       ++a; ++data;
  2368.     }
  2369.     if(!*a)
  2370.       return 1;
  2371.   }
  2372.   return 0;
  2373. }
  2374.  
  2375. /*****************************************************************************/
  2376.  
  2377. #define SIT5_ID 0xA5A5A5A5
  2378.  
  2379. /* header format 20 byte
  2380.   UBYTE[80] header text
  2381.   ULONG     ???
  2382.   ULONG     total archive size
  2383.   ULONG     offset of first entry
  2384.   ULONG     ???
  2385.   ULONG     ???
  2386. */
  2387.  
  2388. #define SIT5AH_ARCSIZE          84
  2389. #define SIT5AH_FIRSTENTRY       88
  2390.  
  2391. /* archive block entry                          directory:
  2392.  0  ULONG     id = SIT5_ID                      <--
  2393.  4  UBYTE     version                           <--
  2394.  5  UBYTE     ???
  2395.  6  UWORD     header size                       <--
  2396.  8  UBYTE     ??? (system ID?)
  2397.  9  UBYTE     type                              <--
  2398. 10  ULONG     creation date                     <--
  2399. 14  ULONG     modification date                 <--
  2400. 18  ULONG     offset of previous entry          <--
  2401. 22  ULONG     offset of next entry              <--
  2402. 26  ULONG     offset of directory entry         <--
  2403. 30  UWORD     filename size                     <--
  2404. 32  UWORD     header crc                        <--
  2405. 34  ULONG     data file size                    offset of first entry
  2406. 38  ULONG     data crunched size                size of complete directory
  2407. 42  UWORD     data old crc16 (not with algo 15)
  2408. 44  UWORD     ???
  2409. 46  UBYTE     data algorithm
  2410.                 none    ==  0
  2411.                 fastest == 13
  2412.                 max     == 15
  2413. 47  UBYTE     password data len                 number of files
  2414. 48  UBYTE[..] password information
  2415. 48+pwdlen            UBYTE[..] filename         <--
  2416. 48+pwdlen+namelen    UWORD     commentsize
  2417. 48+pwdlen+namelen+2  UWORD     ????
  2418. 48+pwdlen+namelen+4  UBYTE[..] comment
  2419.  
  2420.   second block:
  2421.  0  UWORD     ??? (resource exists?)
  2422.  2  UWORD     ???
  2423.  4  ULONG     file type
  2424.  8  ULONG     file creator
  2425. 12  UWORD     finder flags
  2426. 14  UWORD     ???
  2427. 16  ULONG     ??? (macintosh date variable - version 3)
  2428. 20  ULONG     ???
  2429. 24  ULONG     ???
  2430. 28  ULONG     ???
  2431.  
  2432. 32  ULONG     ??? (version 3 misses this one and following?)
  2433.  
  2434. 36  ULONG     rsrc file size
  2435. 40  ULONG     rsrc crunched size
  2436. 44  UWORD     rsrc old crc16 (not with algo 15)
  2437. 46  UWORD     ???
  2438. 48  UBYTE     rsrc algorithm
  2439.  
  2440.   followed by resource fork data
  2441.   followed by data fork data
  2442.  
  2443.   ! The header crc is CRC16 of header size with crc field cleared !
  2444. */
  2445.  
  2446. #define SIT5FH_ID                0
  2447. #define SIT5FH_VERSION           4
  2448. #define SIT5FH_HEADERSIZE        6
  2449. #define SIT5FH_FLAGS             9
  2450. #define SIT5FH_CREATIONDATE     10
  2451. #define SIT5FH_MODDATE          14
  2452. #define SIT5FH_PREVFILE         18
  2453. #define SIT5FH_NEXTFILE         22
  2454. #define SIT5FH_DIRECTORY        26
  2455. #define SIT5FH_FILENAMESIZE     30
  2456. #define SIT5FH_HEADERCRC        32
  2457. #define SIT5FH_DATASIZE         34
  2458. #define SIT5FH_DATACRUNCHSIZE   38
  2459. #define SIT5FH_DATACRC16        42
  2460. #define SIT5FH_DATAALGORITHM    46
  2461. #define SIT5FH_PASSWORDSIZE     47
  2462. #define SIT5FH_FILENAME         48
  2463.  
  2464. #define SIT5FH_FILETYPE          4
  2465. #define SIT5FH_FILECREATOR       8
  2466. #define SIT5FH_FINDERFLAGS      12
  2467. #define SIT5FH_RSRCSIZE         36
  2468. #define SIT5FH_RSRCCRUNCHSIZE   40
  2469. #define SIT5FH_RSRCCRC16        44
  2470. #define SIT5FH_RSRCALGORITHM    48
  2471.  
  2472. #define SIT5FLAGS_DIRECTORY     0x40
  2473. #define SIT5FLAGS_CRYPTED       0x20
  2474. #define SIT5FLAGS_RSRC_FORK     0x10
  2475.  
  2476. ASM(LONG) SIT5_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  2477. REG(a6, struct xadMasterBase *xadMasterBase))
  2478. {
  2479.   LONG err, i, j;
  2480.   ULONG nsize, csize, csize2;
  2481.   STRPTR buffer;
  2482.   struct xadFileInfo *fi, *ldir = 0, *lfi = 0;
  2483.  
  2484.   if((buffer = (STRPTR) xadAllocVec(2048, MEMF_PUBLIC)))
  2485.   {
  2486.     if(!(err = xadHookAccess(XADAC_READ, 100, buffer, ai)))
  2487.     {
  2488.       i = EndGetM32(buffer + SIT5AH_FIRSTENTRY)-100;
  2489.       if(!i || !(err = xadHookAccess(XADAC_INPUTSEEK, i, 0, ai)))
  2490.       {
  2491.         while(!err && ai->xai_InPos < ai->xai_InSize)
  2492.         {
  2493.           if(!(err = xadHookAccess(XADAC_READ, 48, buffer, ai)))
  2494.           {
  2495.             if((buffer[SIT5FH_FLAGS] & SIT5FLAGS_DIRECTORY) && EndGetM32(buffer+SIT5FH_DATASIZE) == 0xFFFFFFFF)
  2496.             {
  2497.               ldir = (struct xadFileInfo *) ldir->xfi_PrivateInfo;
  2498.             }
  2499.             else
  2500.             {
  2501.               i = EndGetM16(buffer+SIT5FH_HEADERSIZE);
  2502.               j = buffer[SIT5FH_VERSION] == 1 ? 36 : 32;
  2503.               if(EndGetM32(buffer+SIT5FH_ID) != SIT5_ID || i + j > 2048-14)
  2504.                 err = XADERR_DATAFORMAT;
  2505.               else if(!(err = xadHookAccess(XADAC_READ, i+j-48, buffer+48, ai)))
  2506.               {
  2507.                 if(!buffer[i+1] || !(err = xadHookAccess(XADAC_READ, 14, buffer+i+j, ai)))
  2508.                 {
  2509.                   nsize = EndGetM16(buffer+SIT5FH_FILENAMESIZE);
  2510.                   if(buffer[SIT5FH_FLAGS] & SIT5FLAGS_DIRECTORY)
  2511.                   {
  2512.                     if(i > SIT5FH_FILENAME + nsize)
  2513.                       csize = EndGetM16(buffer + SIT5FH_FILENAME + nsize);
  2514.                     else
  2515.                       csize = 0;
  2516.  
  2517.                     if((fi = xadAllocObject(XADOBJ_FILEINFO, csize ?
  2518.                     XAD_OBJCOMMENTSIZE : TAG_IGNORE, csize + 1, TAG_DONE)))
  2519.                     {
  2520.                       if((fi->xfi_FileName = MACname(xadMasterBase, ldir, buffer+SIT5FH_FILENAME, nsize, 0)))
  2521.                       {
  2522.                         if(csize)
  2523.                           xadCopyMem(buffer+SIT5FH_FILENAME+nsize+4, fi->xfi_Comment, csize);
  2524.  
  2525.                         xadConvertDates(XAD_DATEMAC, EndGetM32(buffer+SIT5FH_MODDATE), XAD_GETDATEXADDATE,
  2526.                         &fi->xfi_Date, TAG_DONE);
  2527.  
  2528.                         fi->xfi_Flags |= XADFIF_DIRECTORY|XADFIF_XADSTRFILENAME;
  2529.                         fi->xfi_PrivateInfo = (APTR) ldir;
  2530.                         ldir = fi;
  2531.  
  2532.                         err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos, TAG_DONE);
  2533.                       }
  2534.                       else
  2535.                       {
  2536.                         xadFreeObjectA(fi, 0);
  2537.                         err = XADERR_NOMEMORY;
  2538.                       }
  2539.                     }
  2540.                     else
  2541.                       err = XADERR_NOMEMORY;
  2542.                   }
  2543.                   else
  2544.                   {
  2545.                     if(i > SIT5FH_FILENAME + buffer[SIT5FH_PASSWORDSIZE] + nsize)
  2546.                       csize = EndGetM16(buffer + SIT5FH_FILENAME + buffer[SIT5FH_PASSWORDSIZE] + nsize);
  2547.                     else
  2548.                       csize = 0;
  2549.  
  2550.                     csize2 = SITmakecomment(buffer+i+SIT5FH_FILETYPE, EndGetM16(buffer+i+SIT5FH_FINDERFLAGS),
  2551.                     buffer+SIT5FH_FILENAME+buffer[SIT5FH_PASSWORDSIZE]+nsize+4, csize, 0);
  2552.                     if(buffer[i+1]) /* rsrc tree */
  2553.                     {
  2554.                       if((fi = xadAllocObject(XADOBJ_FILEINFO, XAD_OBJPRIVINFOSIZE,
  2555.                       sizeof(struct SITPrivate), csize2 && !EndGetM32(buffer+SIT5FH_DATASIZE) ?
  2556.                       XAD_OBJCOMMENTSIZE : TAG_IGNORE, csize2, TAG_DONE)))
  2557.                       {
  2558.                         if((fi->xfi_FileName = MACname(xadMasterBase, ldir, buffer+SIT5FH_FILENAME+buffer[SIT5FH_PASSWORDSIZE], nsize, 1)))
  2559.                         {
  2560.                           /* if comment field is zero, nothing is done! */
  2561.                           SITmakecomment(buffer+i+SIT5FH_FILETYPE, EndGetM16(buffer+i+SIT5FH_FINDERFLAGS),
  2562.                           buffer+SIT5FH_FILENAME+buffer[SIT5FH_PASSWORDSIZE]+nsize+4, csize, fi->xfi_Comment);
  2563.  
  2564.                           xadConvertDates(XAD_DATEMAC, EndGetM32(buffer+SIT5FH_MODDATE), XAD_GETDATEXADDATE,
  2565.                           &fi->xfi_Date, TAG_DONE);
  2566.  
  2567.                           if(buffer[SIT5FH_FLAGS] & SIT5FLAGS_CRYPTED)
  2568.                           {
  2569.                             fi->xfi_Flags |= XADFIF_CRYPTED;
  2570.                             ai->xai_Flags |= XADAIF_CRYPTED;
  2571.                           }
  2572.  
  2573.                           fi->xfi_CrunchSize = EndGetM32(buffer+i+SIT5FH_RSRCCRUNCHSIZE);
  2574.                           fi->xfi_Size = EndGetM32(buffer+i+SIT5FH_RSRCSIZE);
  2575.  
  2576.                           fi->xfi_Flags |= XADFIF_SEEKDATAPOS|XADFIF_MACRESOURCE|XADFIF_EXTRACTONBUILD|XADFIF_XADSTRFILENAME;
  2577.                           fi->xfi_DataPos = ai->xai_InPos;
  2578.                           lfi = fi;
  2579.  
  2580.                           SITPI(fi)->CRC = EndGetM16(buffer+i+SIT5FH_RSRCCRC16);
  2581.                           SITPI(fi)->Method = buffer[i+SIT5FH_RSRCALGORITHM];
  2582. #ifdef DEBUG
  2583.   if(SITPI(fi)->Method != 0 && SITPI(fi)->Method != 13 && SITPI(fi)->Method != 15)
  2584.   {
  2585.     xadHookAccess(0,SITPI(fi)->Method,0,ai);
  2586.     UnknownRequest(xadMasterBase, SITPI(fi)->Method, ai->xai_InName);
  2587.   }
  2588. #endif
  2589.                           if(SITPI(fi)->Method <= STUFFITMAXALGO)
  2590.                             fi->xfi_EntryInfo = sittypes[SITPI(fi)->Method];
  2591.  
  2592.                           err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos+fi->xfi_CrunchSize, TAG_DONE);
  2593.                         }
  2594.                         else
  2595.                         {
  2596.                           xadFreeObjectA(fi, 0);
  2597.                           err = XADERR_NOMEMORY;
  2598.                         }
  2599.                       }
  2600.                       else
  2601.                         err = XADERR_NOMEMORY;
  2602.                     }
  2603.  
  2604.                     if(!err && (EndGetM32(buffer+SIT5FH_DATASIZE) || !buffer[i+1]))
  2605.                     {
  2606.                       if((fi = xadAllocObject(XADOBJ_FILEINFO, XAD_OBJPRIVINFOSIZE,
  2607.                       sizeof(struct SITPrivate), csize2 ? XAD_OBJCOMMENTSIZE : TAG_IGNORE,
  2608.                       csize2, TAG_DONE)))
  2609.                       {
  2610.                         if((fi->xfi_FileName = MACname(xadMasterBase, ldir, buffer+SIT5FH_FILENAME+buffer[SIT5FH_PASSWORDSIZE], nsize, 0)))
  2611.                         {
  2612.                           SITmakecomment(buffer+i+SIT5FH_FILETYPE, EndGetM16(buffer+i+SIT5FH_FINDERFLAGS),
  2613.                           buffer+SIT5FH_FILENAME+buffer[SIT5FH_PASSWORDSIZE]+nsize+4, csize, fi->xfi_Comment);
  2614.                           if(buffer[i+1])
  2615.                           {
  2616.                             fi->xfi_MacFork = lfi;
  2617.                             lfi->xfi_MacFork = fi;
  2618.                           }
  2619.  
  2620.                           xadConvertDates(XAD_DATEMAC, EndGetM32(buffer+SIT5FH_MODDATE), XAD_GETDATEXADDATE,
  2621.                           &fi->xfi_Date, TAG_DONE);
  2622.  
  2623.                           if(buffer[SIT5FH_FLAGS] & SIT5FLAGS_CRYPTED)
  2624.                           {
  2625.                             fi->xfi_Flags |= XADFIF_CRYPTED;
  2626.                             ai->xai_Flags |= XADAIF_CRYPTED;
  2627.                           }
  2628.  
  2629.                           fi->xfi_CrunchSize = EndGetM32(buffer+SIT5FH_DATACRUNCHSIZE);
  2630.                           fi->xfi_Size = EndGetM32(buffer+SIT5FH_DATASIZE);
  2631.  
  2632.                           fi->xfi_Flags |= XADFIF_SEEKDATAPOS|XADFIF_MACDATA|XADFIF_EXTRACTONBUILD|XADFIF_XADSTRFILENAME;
  2633.                           fi->xfi_DataPos = ai->xai_InPos;
  2634.  
  2635.                           SITPI(fi)->CRC = EndGetM16(buffer+SIT5FH_DATACRC16);
  2636.                           SITPI(fi)->Method = buffer[SIT5FH_DATAALGORITHM];
  2637. #ifdef DEBUG
  2638.   if(SITPI(fi)->Method != 0 && SITPI(fi)->Method != 13 && SITPI(fi)->Method != 15)
  2639.   {
  2640.     xadHookAccess(0,SITPI(fi)->Method,0,ai);
  2641.     UnknownRequest(xadMasterBase, SITPI(fi)->Method, ai->xai_InName);
  2642.   }
  2643. #endif
  2644.                           if(SITPI(fi)->Method <= STUFFITMAXALGO)
  2645.                             fi->xfi_EntryInfo = sittypes[SITPI(fi)->Method];
  2646.  
  2647.                           err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos+fi->xfi_CrunchSize, TAG_DONE);
  2648.                         }
  2649.                         else
  2650.                         {
  2651.                           xadFreeObjectA(fi, 0);
  2652.                           err = XADERR_NOMEMORY;
  2653.                         }
  2654.                       }
  2655.                       else
  2656.                         err = XADERR_NOMEMORY;
  2657.                     }
  2658.                   }
  2659.                 }
  2660.               }
  2661.             }
  2662.           }
  2663.         }
  2664.       }
  2665.     }
  2666.     xadFreeObjectA(buffer,0);
  2667.   }
  2668.   else
  2669.     err = XADERR_NOMEMORY;
  2670.  
  2671.   if(err)
  2672.   {
  2673.     ai->xai_Flags |= XADAIF_FILECORRUPT;
  2674.     ai->xai_LastError = err;
  2675.   }
  2676.  
  2677. #ifdef DEBUG
  2678.   if(err || (ai->xai_Flags & XADAIF_CRYPTED))
  2679.     UnknownRequest(xadMasterBase, 0, ai->xai_InName);
  2680. #endif
  2681.  
  2682.   return (ai->xai_FileInfo ? 0 : err);
  2683. }
  2684.  
  2685. /*****************************************************************************/
  2686.  
  2687. ASM(BOOL) SIT5EXE_RecogData(REG(d0, ULONG size), REG(a0, UBYTE *data),
  2688. REG(a6, struct xadMasterBase *xadMasterBase))
  2689. { CPUCHECK
  2690.   if(data[0] == 'M' && data[1] == 'Z' && EndGetM32(data+4100) == 0x4203e853)
  2691.     return 1;
  2692.   return 0;
  2693. }
  2694.  
  2695. /*****************************************************************************/
  2696.  
  2697. ASM(LONG) SIT5EXE_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  2698. REG(a6, struct xadMasterBase *xadMasterBase))
  2699. {
  2700.   LONG err;
  2701.  
  2702.   if(!(err = xadHookAccess(XADAC_INPUTSEEK, 0x1A000, 0, ai)))
  2703.     err = SIT5_GetInfo(ai, xadMasterBase);
  2704.   return err;
  2705. }
  2706.  
  2707. /*****************************************************************************/
  2708.  
  2709. ASM(BOOL) MacBinary_RecogData(REG(d0, ULONG size), REG(a0, UBYTE *data),
  2710. REG(a6, struct xadMasterBase *xadMasterBase))
  2711. { CPUCHECK
  2712.   if(data[0] <= 1 && data[1] >= 1 && data[1] <= 63 && !data[74] && !data[82])
  2713.   {
  2714.     if(DoCRC(data, 124) == EndGetM16(data+124))
  2715.     {
  2716.       if(data[102] == 'm' && data[103] == 'B' && data[104] == 'I' &&
  2717.       data[105] == 'N')
  2718.         return 3; /* is MacBinaryIII */
  2719.       return 2; /* MacBinaryII */
  2720.     }
  2721.     else if(!data[0]) /* test for MacBinary type I */
  2722.     {
  2723.       if(EndGetM32(data+83) <= 0xFFFFFF && EndGetM32(data+87) <= 0xFFFFFF)
  2724.       {
  2725.         LONG i;
  2726.  
  2727.         for(i = 65; i < 65+8; ++i) /* check finder flags */
  2728.         {
  2729.           if(data[i] < 0x20)
  2730.             return 0;
  2731.         }
  2732.         for(i = 0; i < data[1]; ++i) /* there can be no zero in name! */
  2733.         {
  2734.           if(!data[i+2])
  2735.             return 0;
  2736.         }
  2737.         return 1;
  2738.       }
  2739.     }
  2740.   }
  2741.  
  2742.   return 0;
  2743. }
  2744.  
  2745. /*****************************************************************************/
  2746.  
  2747. ASM(LONG) MacBinary_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  2748. REG(a6, struct xadMasterBase *xadMasterBase))
  2749. {
  2750.   struct xadFileInfo *fi, *lfi, *ldir = 0;
  2751.   LONG err = 0, type, rsize, dsize, csize, i;
  2752.   UBYTE header[128];
  2753.  
  2754.   while(!err && ai->xai_InPos + 128 <= ai->xai_InSize)
  2755.   {
  2756.     if(!(err = xadHookAccess(XADAC_READ, 128, header, ai)))
  2757.     {
  2758.       type = MacBinary_RecogData(128, header, xadMasterBase);
  2759.  
  2760. #ifdef DEBUG
  2761.   if(header[0] == 1 || (ai->xai_InPos != 128 && type))
  2762.     UnknownRequest(xadMasterBase, 0, ai->xai_InName);
  2763. #endif
  2764.  
  2765.       if(!type)
  2766.         err = XADERR_DATAFORMAT;
  2767.       else if(header[0] == 1 && header[65] == 'f' && header[66] == 'o' && header[67] == 'l' &&
  2768.       header[68] == 'd')
  2769.       {
  2770.         if(!header[1] && ldir) /* stop block????? - no clear standard description */
  2771.         {
  2772.           ldir = (struct xadFileInfo *) ldir->xfi_PrivateInfo;
  2773.         }
  2774.         else if((fi = xadAllocObjectA(XADOBJ_FILEINFO, 0)))
  2775.         {
  2776.           if((fi->xfi_FileName = MACname(xadMasterBase, ldir, header+2, header[1], 0)))
  2777.           {
  2778.             fi->xfi_Flags |= XADFIF_DIRECTORY|XADFIF_XADSTRFILENAME;
  2779.             xadConvertDates(XAD_DATEMAC, EndGetM32(header+95), XAD_GETDATEXADDATE, &fi->xfi_Date, TAG_DONE);
  2780.             fi->xfi_PrivateInfo = (APTR) ldir;
  2781.             ldir = fi;
  2782.             err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos, TAG_DONE);
  2783.           }
  2784.           else
  2785.           {
  2786.             xadFreeObjectA(fi, 0);
  2787.             err = XADERR_NOMEMORY;
  2788.           }
  2789.         }
  2790.         else
  2791.           err = XADERR_NOMEMORY;
  2792.       }
  2793.       else
  2794.       {
  2795.         csize = SITmakecomment(header+65, (header[73]<<8)+(type>1 ? header[101] : 0), 0, 0, 0);
  2796.         rsize = EndGetM32(header+87);
  2797.         dsize = EndGetM32(header+83);
  2798.         lfi = 0;
  2799.  
  2800.         if(dsize) /* data fork */
  2801.         {
  2802.           if((fi = xadAllocObject(XADOBJ_FILEINFO, csize ? XAD_OBJCOMMENTSIZE
  2803.           : TAG_IGNORE, csize, TAG_DONE)))
  2804.           {
  2805.             if((fi->xfi_FileName = MACname(xadMasterBase, ldir, header+2, header[1], 0)))
  2806.             {
  2807.               /* if comment field is zero, nothing is done! */
  2808.               SITmakecomment(header+65, (header[73]<<8)+(type>1 ? header[101] : 0), 0, 0, fi->xfi_Comment);
  2809.  
  2810.               fi->xfi_CrunchSize = fi->xfi_Size = dsize;
  2811.               lfi = fi;
  2812.  
  2813.               fi->xfi_Flags |= XADFIF_SEEKDATAPOS|XADFIF_MACDATA|XADFIF_EXTRACTONBUILD|XADFIF_XADSTRFILENAME;
  2814.               fi->xfi_DataPos = ai->xai_InPos;
  2815.  
  2816.               xadConvertDates(XAD_DATEMAC, EndGetM32(header+95), XAD_GETDATEXADDATE, &fi->xfi_Date, TAG_DONE);
  2817.  
  2818.               i = (fi->xfi_CrunchSize+127)&(~127);
  2819.               if(ai->xai_InSize-ai->xai_InPos == fi->xfi_CrunchSize)
  2820.                i = fi->xfi_CrunchSize;
  2821.               err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos+i, TAG_DONE);
  2822.             }
  2823.             else
  2824.             {
  2825.               xadFreeObjectA(fi, 0);
  2826.               err = XADERR_NOMEMORY;
  2827.             }
  2828.           }
  2829.           else
  2830.             err = XADERR_NOMEMORY;
  2831.         }
  2832.         if(!err && rsize) /* resource fork */
  2833.         {
  2834.           if((fi = xadAllocObject(XADOBJ_FILEINFO, dsize || !csize ? TAG_IGNORE
  2835.           : XAD_OBJCOMMENTSIZE, csize, TAG_DONE)))
  2836.           {
  2837.             if((fi->xfi_FileName = MACname(xadMasterBase, ldir, header+2, header[1], 1)))
  2838.             {
  2839.               /* if comment field is zero, nothing is done! */
  2840.               SITmakecomment(header+65, (header[73]<<8)+(type>1 ? header[101] : 0), 0, 0, fi->xfi_Comment);
  2841.  
  2842.               fi->xfi_CrunchSize = fi->xfi_Size = rsize;
  2843.  
  2844.               fi->xfi_Flags |= XADFIF_SEEKDATAPOS|XADFIF_MACRESOURCE|XADFIF_EXTRACTONBUILD|XADFIF_XADSTRFILENAME;
  2845.               fi->xfi_DataPos = ai->xai_InPos;
  2846.  
  2847.               if((fi->xfi_MacFork = lfi))
  2848.                 lfi->xfi_MacFork = fi;
  2849.  
  2850.               xadConvertDates(XAD_DATEMAC, EndGetM32(header+95), XAD_GETDATEXADDATE, &fi->xfi_Date, TAG_DONE);
  2851.  
  2852.               i = (fi->xfi_CrunchSize+127)&(~127);
  2853.               if(ai->xai_InSize-ai->xai_InPos == fi->xfi_CrunchSize)
  2854.                i = fi->xfi_CrunchSize;
  2855.               err = xadAddFileEntry(fi, ai, XAD_SETINPOS, ai->xai_InPos+i, TAG_DONE);
  2856.             }
  2857.             else
  2858.             {
  2859.               xadFreeObjectA(fi, 0);
  2860.               err = XADERR_NOMEMORY;
  2861.             }
  2862.           }
  2863.           else
  2864.             err = XADERR_NOMEMORY;
  2865.         }
  2866.         if(!err && type > 1 && (csize = EndGetM16(header+99)))
  2867.         {
  2868.           err = xadHookAccess(XADAC_INPUTSEEK, (csize+127)&(~127), 0, ai);
  2869.         }
  2870.       }
  2871.     }
  2872.   }
  2873.  
  2874.   if(err)
  2875.   {
  2876.     ai->xai_Flags |= XADAIF_FILECORRUPT;
  2877.     ai->xai_LastError = err;
  2878.   }
  2879.  
  2880.   return (ai->xai_FileInfo ? 0 : err);
  2881. }
  2882.  
  2883. /*****************************************************************************/
  2884.  
  2885. ASM(LONG) MacBinary_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  2886. REG(a6, struct xadMasterBase *xadMasterBase))
  2887. {
  2888.   return xadHookAccess(XADAC_COPY, ai->xai_CurFile->xfi_Size, 0, ai);
  2889. }
  2890.  
  2891. /*****************************************************************************/
  2892.  
  2893. ASM(BOOL) PackIt_RecogData(REG(d0, ULONG size), REG(a0, UBYTE *data),
  2894. REG(a6, struct xadMasterBase *xadMasterBase))
  2895. { CPUCHECK
  2896.   if(data[0] == 'P' && data[1] == 'M' && data[2] == 'a' &&
  2897.   (data[3] == 'g' || (data[3] >= '0' && data[3] <= '9')))
  2898.     return 1;
  2899.  
  2900.   return 0;
  2901. }
  2902.  
  2903. /*****************************************************************************/
  2904.  
  2905. #define PIT_NLEN       0
  2906. #define PIT_NAME       1
  2907. #define PIT_TYPE      64
  2908. #define PIT_AUTH      68
  2909. #define PIT_FLAG      72
  2910. #define PIT_LOCK      74
  2911. #define PIT_DLEN      76
  2912. #define PIT_RLEN      80
  2913. #define PIT_CTIME     84
  2914. #define PIT_MTIME     88
  2915. #define PIT_HDRCRC    92
  2916. #define PIT_HDRBYTES  94
  2917.  
  2918. struct PITPrivate {
  2919.   ULONG SkipHead;
  2920.   ULONG SkipEnd;
  2921.   UBYTE Method;
  2922. };
  2923.  
  2924. #define PITPI(a)        ((struct PITPrivate *) ((a)->xfi_PrivateInfo))
  2925.  
  2926. /* This functions extracts the first header bytes form the data file
  2927. you selected */
  2928. static UBYTE PackIt_Put(struct xadInOut *io, UBYTE data)
  2929. {
  2930.   ULONG a;
  2931.  
  2932.   a = (ULONG) io->xio_PutFuncPrivate;
  2933.   if(!io->xio_OutSize && !a)
  2934.   {
  2935.     io->xio_Error = XADERR_DECRUNCH;
  2936.     io->xio_Flags |= XADIOF_ERROR;
  2937.   }
  2938.   else
  2939.   {
  2940.     if(io->xio_OutSize)
  2941.     {
  2942.       io->xio_OutBuffer[io->xio_OutBufferPos++] = data;
  2943.       if(!--io->xio_OutSize)
  2944.       {
  2945.         if(DoCRC(io->xio_OutBuffer, PIT_HDRBYTES-2)
  2946.         != EndGetM16(io->xio_OutBuffer+PIT_HDRCRC))
  2947.         {
  2948.           io->xio_Error = XADERR_CHECKSUM;
  2949.           io->xio_Flags |= XADIOF_ERROR;
  2950.         }
  2951.         else
  2952.         {
  2953.           a = EndGetM32(io->xio_OutBuffer+PIT_RLEN)
  2954.              +EndGetM32(io->xio_OutBuffer+PIT_DLEN)+2;
  2955.         }
  2956.       }
  2957.     }
  2958.     else
  2959.     {
  2960.       if(!--a)
  2961.         io->xio_Flags |= XADIOF_LASTOUTBYTE;
  2962.     }
  2963.  
  2964.     io->xio_PutFuncPrivate = (APTR) a;
  2965.   }
  2966.  
  2967.   return data;
  2968. }
  2969.  
  2970. ASM(LONG) PackIt_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  2971. REG(a6, struct xadMasterBase *xadMasterBase))
  2972. {
  2973.   struct xadFileInfo *fi, *lfi;
  2974.   LONG err = 0;
  2975.   ULONG rsize, dsize, csize, crsize = 0, pos;
  2976.   STRPTR entryinfo;
  2977.   UBYTE header[PIT_HDRBYTES], type[4];
  2978.  
  2979.   while(!err && ai->xai_InPos + 4 <= ai->xai_InSize)
  2980.   {
  2981.     if(!(err = xadHookAccess(XADAC_READ, 4, type, ai)))
  2982.     {
  2983.       entryinfo = header; /* to silent compiler warnings */
  2984.       pos = ai->xai_InPos;
  2985.       if(type[0] == 'P' && type[1] == 'E' && type[2] == 'n' && type[3] == 'd')
  2986.         break;
  2987.       else if(type[0] != 'P' || type[1] != 'M' || type[2] != 'a')
  2988.         err = XADERR_DATAFORMAT;
  2989.       else if(type[3] == '4')
  2990.       {
  2991.         struct xadInOut *io;
  2992.  
  2993.         if((io = xadIOAlloc(XADIOF_ALLOCINBUFFER|XADIOF_NOCRC32|XADIOF_NOCRC16, ai, xadMasterBase)))
  2994.         {
  2995.           io->xio_PutFunc = PackIt_Put;
  2996.           io->xio_InSize = ai->xai_InSize-ai->xai_InPos;
  2997.           io->xio_OutSize = PIT_HDRBYTES;
  2998.           io->xio_OutBuffer = header;
  2999.           entryinfo = "Huffmann";
  3000.  
  3001.           err = SIT_huffman(io);
  3002.           crsize = (ai->xai_InSize-io->xio_InSize)-pos;
  3003.           xadFreeObjectA(io, 0);
  3004.         }
  3005.         else
  3006.           err = XADERR_NOMEMORY;
  3007.       }
  3008.       else if(type[3] == 'g')
  3009.       {
  3010.         if(!(err = xadHookAccess(XADAC_READ, PIT_HDRBYTES, header, ai)))
  3011.         {
  3012.           if(DoCRC(header, PIT_HDRBYTES-2) != EndGetM16(header+PIT_HDRCRC))
  3013.             err = XADERR_CHECKSUM;
  3014.           else
  3015.           {
  3016.             entryinfo = "NoComp";
  3017.             crsize = PIT_HDRBYTES+EndGetM32(header+PIT_RLEN)+EndGetM32(header+PIT_DLEN)+2;
  3018.           }
  3019.         }
  3020.       }
  3021.       else
  3022.         err = XADERR_DATAFORMAT;
  3023.  
  3024.       if(!err)
  3025.       {
  3026.         csize = SITmakecomment(header+PIT_TYPE, EndGetM16(header+PIT_FLAG), 0, 0, 0);
  3027.         rsize = EndGetM32(header+PIT_RLEN);
  3028.         dsize = EndGetM32(header+PIT_DLEN);
  3029.         lfi = 0;
  3030.  
  3031.         if(dsize) /* data fork */
  3032.         {
  3033.           if((fi = xadAllocObject(XADOBJ_FILEINFO, XAD_OBJPRIVINFOSIZE,
  3034.           sizeof(struct PITPrivate), csize ? XAD_OBJCOMMENTSIZE : TAG_IGNORE,
  3035.           csize, TAG_DONE)))
  3036.           {
  3037.             if((fi->xfi_FileName = MACname(xadMasterBase, 0, header+PIT_NAME, header[PIT_NLEN], 0)))
  3038.             {
  3039.               /* if comment field is zero, nothing is done! */
  3040.               SITmakecomment(header+PIT_TYPE, EndGetM16(header+PIT_FLAG), 0, 0, fi->xfi_Comment);
  3041.  
  3042.               fi->xfi_Size = dsize;
  3043.               fi->xfi_CrunchSize = crsize;
  3044.               if(rsize)
  3045.               {
  3046.                 fi->xfi_Flags |= XADFIF_GROUPED;
  3047.                 fi->xfi_GroupCrSize = crsize;
  3048.               }
  3049.               lfi = fi;
  3050.  
  3051.               fi->xfi_Flags |= XADFIF_SEEKDATAPOS|XADFIF_MACDATA|XADFIF_EXTRACTONBUILD|XADFIF_XADSTRFILENAME;
  3052.               fi->xfi_DataPos = pos;
  3053.  
  3054.               xadConvertDates(XAD_DATEMAC, EndGetM32(header+PIT_MTIME), XAD_GETDATEXADDATE,
  3055.               &fi->xfi_Date, TAG_DONE);
  3056.  
  3057.               PITPI(fi)->Method   = type[3];
  3058.               PITPI(fi)->SkipHead = PIT_HDRBYTES;
  3059.               PITPI(fi)->SkipEnd = rsize+2;
  3060.               fi->xfi_EntryInfo = entryinfo;
  3061.  
  3062.               err = xadAddFileEntry(fi, ai, XAD_SETINPOS, pos+crsize, TAG_DONE);
  3063.             }
  3064.             else
  3065.             {
  3066.               xadFreeObjectA(fi, 0);
  3067.               err = XADERR_NOMEMORY;
  3068.             }
  3069.           }
  3070.           else
  3071.             err = XADERR_NOMEMORY;
  3072.         }
  3073.         if(!err && rsize) /* resource fork */
  3074.         {
  3075.           if((fi = xadAllocObject(XADOBJ_FILEINFO, XAD_OBJPRIVINFOSIZE, sizeof(struct PITPrivate),
  3076.           dsize || !csize ? TAG_IGNORE : XAD_OBJCOMMENTSIZE, csize, TAG_DONE)))
  3077.           {
  3078.             if((fi->xfi_FileName = MACname(xadMasterBase, 0, header+PIT_NAME, header[PIT_NLEN], 1)))
  3079.             {
  3080.               /* if comment field is zero, nothing is done! */
  3081.               SITmakecomment(header+PIT_TYPE, EndGetM16(header+PIT_FLAG), 0, 0, fi->xfi_Comment);
  3082.  
  3083.               fi->xfi_Size = rsize;
  3084.               fi->xfi_CrunchSize = crsize;
  3085.               fi->xfi_Flags |= XADFIF_SEEKDATAPOS|XADFIF_MACRESOURCE|XADFIF_EXTRACTONBUILD|XADFIF_XADSTRFILENAME;
  3086.               fi->xfi_DataPos = pos;
  3087.  
  3088.               PITPI(fi)->Method   = type[3];
  3089.               PITPI(fi)->SkipHead = PIT_HDRBYTES+dsize;
  3090.               PITPI(fi)->SkipEnd = 2;
  3091.               fi->xfi_EntryInfo = entryinfo;
  3092.  
  3093.               if((fi->xfi_MacFork = lfi))
  3094.               {
  3095.                 lfi->xfi_MacFork = fi;
  3096.                 fi->xfi_GroupCrSize = crsize;
  3097.                 fi->xfi_Flags |= XADFIF_ENDOFGROUP|XADFIF_GROUPED;
  3098.               }
  3099.  
  3100.               xadConvertDates(XAD_DATEMAC, EndGetM32(header+PIT_MTIME), XAD_GETDATEXADDATE,
  3101.               &fi->xfi_Date, TAG_DONE);
  3102.  
  3103.               err = xadAddFileEntry(fi, ai, XAD_SETINPOS, pos+crsize, TAG_DONE);
  3104.             }
  3105.             else
  3106.             {
  3107.               xadFreeObjectA(fi, 0);
  3108.               err = XADERR_NOMEMORY;
  3109.             }
  3110.           }
  3111.           else
  3112.             err = XADERR_NOMEMORY;
  3113.         }
  3114.       }
  3115.     }
  3116.   }
  3117.  
  3118.   if(err)
  3119.   {
  3120.     ai->xai_Flags |= XADAIF_FILECORRUPT;
  3121.     ai->xai_LastError = err;
  3122.   }
  3123.  
  3124.   return (ai->xai_FileInfo ? 0 : err);
  3125. }
  3126.  
  3127. /*****************************************************************************/
  3128.  
  3129. struct PackItOutPrivate {
  3130.   ULONG Header;
  3131.   ULONG SkipStart;
  3132.   ULONG Data;
  3133.   ULONG SkipEnd;
  3134.   ULONG CRC;
  3135.   UWORD CRCValue;
  3136. };
  3137.  
  3138. static void PackIt_Out(struct xadInOut *io, ULONG size)
  3139. {
  3140.   struct PackItOutPrivate *p;
  3141.   ULONG bufpos = 0, cursize, i;
  3142.   UWORD crc;
  3143.  
  3144.   p = (struct PackItOutPrivate *) io->xio_OutFuncPrivate;
  3145.   if(p->Header)
  3146.   {
  3147.     if((cursize = p->Header) > size)
  3148.       cursize = size;
  3149.     size -= cursize;
  3150.     bufpos += cursize;
  3151.     p->Header -= cursize;
  3152.   }
  3153.   if(size)
  3154.   {
  3155.     if((cursize = p->SkipStart+p->Data+p->SkipEnd) > size)
  3156.       cursize = size;
  3157.  
  3158.     crc = io->xio_CRC16;
  3159.     for(i = 0; i < cursize; ++i)
  3160.       crc = crctable[((crc>>8) ^ io->xio_OutBuffer[bufpos+i]) & 0xFF] ^ (crc<<8);
  3161.     io->xio_CRC16 = crc;
  3162.  
  3163.     if(p->SkipStart)
  3164.     {
  3165.       if((cursize = p->SkipStart) > size)
  3166.         cursize = size;
  3167.       size -= cursize;
  3168.       bufpos += cursize;
  3169.       p->SkipStart -= cursize;
  3170.     }
  3171.     if(size)
  3172.     {
  3173.       if(p->Data)
  3174.       {
  3175.         struct xadMasterBase *xadMasterBase = io->xio_xadMasterBase;
  3176.         if((cursize = p->Data) > size)
  3177.           cursize = size;
  3178.         if((io->xio_Error = xadHookAccess(XADAC_WRITE, cursize, io->xio_OutBuffer
  3179.         + bufpos, io->xio_ArchiveInfo)))
  3180.           io->xio_Flags |= XADIOF_ERROR;
  3181.         size -= cursize;
  3182.         bufpos += cursize;
  3183.         p->Data -= cursize;
  3184.       }
  3185.       if(p->SkipEnd && size)
  3186.       {
  3187.         if((cursize = p->SkipEnd) > size)
  3188.           cursize = size;
  3189.         size -= cursize;
  3190.         bufpos += cursize;
  3191.         p->SkipEnd -= cursize;
  3192.       }
  3193.     }
  3194.   }
  3195.   /* if there is size left, this must be CRC */
  3196.   while(size && p->CRC)
  3197.   {
  3198.     p->CRCValue = (p->CRCValue<<8) | io->xio_OutBuffer[bufpos++];
  3199.     --p->CRC;
  3200.     --size;
  3201.   }
  3202.   if(!p->CRC && io->xio_CRC16 != p->CRCValue && !io->xio_Error)
  3203.   {
  3204.     io->xio_Error = XADERR_CHECKSUM;
  3205.     io->xio_Flags |= XADIOF_ERROR;
  3206.   }
  3207. }
  3208.  
  3209. ASM(LONG) PackIt_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  3210. REG(a6, struct xadMasterBase *xadMasterBase))
  3211. {
  3212.   struct xadFileInfo *fi;
  3213.   struct xadInOut *io;
  3214.   LONG err;
  3215.   struct PackItOutPrivate p;
  3216.  
  3217.   fi = ai->xai_CurFile;
  3218.  
  3219.   if((io = xadIOAlloc(XADIOF_ALLOCINBUFFER|XADIOF_ALLOCOUTBUFFER|
  3220.   XADIOF_COMPLETEOUTFUNC|XADIOF_NOCRC32|XADIOF_NOCRC16, ai, xadMasterBase)))
  3221.   {
  3222.     p.Header = PIT_HDRBYTES;
  3223.     p.SkipStart = PITPI(fi)->SkipHead-p.Header;
  3224.     p.Data = fi->xfi_Size;
  3225.     p.SkipEnd = PITPI(fi)->SkipEnd-2;
  3226.     p.CRC = 2;
  3227.     p.CRCValue = 0;
  3228.  
  3229.     io->xio_OutFunc = PackIt_Out;
  3230.     io->xio_OutFuncPrivate = &p;
  3231.     io->xio_InSize = fi->xfi_CrunchSize;
  3232.     io->xio_OutSize = p.Header+p.SkipStart+p.Data+p.SkipEnd+p.CRC;
  3233.  
  3234.     switch(PITPI(fi)->Method)
  3235.     {
  3236.     case 'g':
  3237.       while(!(io->xio_Flags & (XADIOF_LASTOUTBYTE|XADIOF_ERROR)))
  3238.         xadIOPutChar(io, xadIOGetChar(io));
  3239.       err = io->xio_Error;
  3240.       break;
  3241.     case '4':
  3242.       err = SIT_huffman(io);
  3243.       break;
  3244.     default:
  3245.       err = XADERR_DATAFORMAT;
  3246.     }
  3247.     if(!err)
  3248.       err = xadIOWriteBuf(io);
  3249.     xadFreeObjectA(io, 0);
  3250.   }
  3251.   else
  3252.     err = XADERR_NOMEMORY;
  3253.  
  3254.   return err;
  3255. }
  3256.  
  3257. /*****************************************************************************/
  3258.  
  3259. const struct xadClient PackIt_Client = {
  3260. NEXTCLIENT, XADCLIENT_VERSION, XADMASTERVERSION, PACKIT_VERSION, PACKIT_REVISION,
  3261. 4, XADCF_FILEARCHIVER|XADCF_FREEFILEINFO|XADCF_FREEXADSTRINGS, XADCID_PACKIT, "PackIt",
  3262. (BOOL (*)()) PackIt_RecogData, (LONG (*)()) PackIt_GetInfo,
  3263. (LONG (*)()) PackIt_UnArchive, 0};
  3264.  
  3265. const struct xadClient MacBinary_Client = {
  3266. &PackIt_Client, XADCLIENT_VERSION, XADMASTERVERSION, MACBINARY_VERSION, MACBINARY_REVISION,
  3267. 128, XADCF_FILEARCHIVER|XADCF_FREEFILEINFO|XADCF_FREEXADSTRINGS, XADCID_MACBINARY, "MacBinary",
  3268. (BOOL (*)()) MacBinary_RecogData, (LONG (*)()) MacBinary_GetInfo,
  3269. (LONG (*)()) MacBinary_UnArchive, 0};
  3270.  
  3271. const struct xadClient SIT5EXE_Client = {
  3272. &MacBinary_Client, XADCLIENT_VERSION, XADMASTERVERSION, SIT5EXE_VERSION, SIT5EXE_REVISION,
  3273. 8192, XADCF_FILEARCHIVER|XADCF_FREEFILEINFO|XADCF_FREEXADSTRINGS, XADCID_SIT5EXE, "StuffIt 5 MS-EXE",
  3274. (BOOL (*)()) SIT5EXE_RecogData, (LONG (*)()) SIT5EXE_GetInfo,
  3275. (LONG (*)()) SIT_UnArchive, 0};
  3276.  
  3277. const struct xadClient SIT5_Client = {
  3278. &SIT5EXE_Client, XADCLIENT_VERSION, XADMASTERVERSION, SIT5_VERSION, SIT5_REVISION,
  3279. 100, XADCF_FILEARCHIVER|XADCF_FREEFILEINFO|XADCF_FREEXADSTRINGS, XADCID_SIT5, "StuffIt 5",
  3280. (BOOL (*)()) SIT5_RecogData, (LONG (*)()) SIT5_GetInfo,
  3281. (LONG (*)()) SIT_UnArchive, 0};
  3282.  
  3283. const struct xadClient SIT_Client = {
  3284. &SIT5_Client, XADCLIENT_VERSION, XADMASTERVERSION, SIT_VERSION, SIT_REVISION,
  3285. 22, XADCF_FILEARCHIVER|XADCF_FREEFILEINFO|XADCF_FREEXADSTRINGS, XADCID_SIT, "StuffIt",
  3286. (BOOL (*)()) SIT_RecogData, (LONG (*)()) SIT_GetInfo,
  3287. (LONG (*)()) SIT_UnArchive, 0};
  3288.  
  3289. #endif /* XADMASTER_STUFFIT_C */
  3290.